Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipselink-users] Configuring History Policy for @OneToMany

Your customizer should be run twice on startup as you have the customizer set
for two classes, and each class needs to be customized.

The start_time may differ slightly for each insert, as the insert may occur
at different times (more than one millisecond), this should not matter
however, the relationship between the rows is based on a range of time.  It
would probably be better to have only a single transaction start time used
however, please log a bug for this.

If the merge only changed the Builder but not the name, then only the build
will be inserted into.  Both versions of the building will have the same
name as the date range encompasses both.

If you created a historical session for the point in time that the Building
was inserted, but before the Name was inserted, then it may not have a name
if they inserts took more than 1 millisecond, but any point in time after
the insert of the Name would get both correctly.



Daniel Rickardsson wrote:
> 
> Hi All,
> 
> My problem is about to get the history working for the relation OneToMany.
> 
> I have set up a simple project with the following entities:
> * Building
> * BuildingName
> 
> Here is my Building:
> @Entity
> @Historical
> @Customizer(AnnotatedCustomizers.class)
> public class Building extends AbstractEntity {
>     ...
>     ...
>     @PrivateOwned
>     @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL,
> mappedBy = "building")
>     private Collection<BuildingName> names = new
> ArrayList<BuildingName>();
>     ...
>     ...
>     public void addName(final BuildingName buildingName) {
>         buildingName.setBuilding(this);
>         this.names.add(buildingName);
>     }
> }
> 
> Here is my BuildingName:
> @Entity
> @Historical
> @Customizer(AnnotatedCustomizers.class)
> public class BuildingName extends AbstractEntity {
>     ...
>     ...
>     @ManyToOne
>     @JoinColumn(nullable = false)
>     private Building building;
> }
> 
> The AnnotatedCustomizers gets triggered for all annotations in class, and
> for the @Historical we call:
> 
> public class HistorySupport implements
> AnnotatedDescriptorCustomizer<Historical> {
>     ...
>     ...
> 
>     @Override
>     public void customize(final ClassDescriptor descriptor, final
> Historical annotation) throws Exception {
>         this.customize(descriptor);
>     }
> 
>     @Override
>     public void customize(final ClassDescriptor descriptor) throws
> Exception {
>         if (descriptor.getTableName().equals("BUILDING")) {
>             HistoryPolicy policy = new HistoryPolicy();
>             policy.addStartFieldName("BUILDING.ROW_START");
>             policy.addEndFieldName("BUILDING.ROW_END");
> 
>             String sourceTableName = descriptor.getTableName();
>             this.logger.debug("descriptor tableName {}", sourceTableName);
> 
>             policy.addHistoryTableName("BUILDING", "BUILDING_HIST");
> 
>             policy.setShouldHandleWrites(true);
> 
>             descriptor.setHistoryPolicy(policy);
>         } else {
>             HistoryPolicy policy = new HistoryPolicy();
>             policy.addStartFieldName("BUILDINGNAME.ROW_START");
>             policy.addEndFieldName("BUILDINGNAME.ROW_END");
> 
>             String sourceTableName = descriptor.getTableName();
>             this.logger.debug("descriptor tableName {}", sourceTableName);
> 
>             policy.addHistoryTableName("BUILDINGNAME",
> "BUILDINGNAME_HIST");
> 
>             policy.setShouldHandleWrites(true);
> 
>             descriptor.setHistoryPolicy(policy);
>         }
>     }
> }
> 
> When persisting the above code is triggered twice... so there will be one
> HistoryPolicy for each entity?! This does not feel right.
> 
> When testing:
> * persist of Building and BuildingName => EclipseLink writes to
> _HIST-tables but the ROW_START differs.
> * and then doing a merge of Building gives me another row in _HIST-table
> for Building but not for BuildingName?
> * and then when I query with a HistoricalSession (DateTime for ROW_START
> in Building (HIST) when first inserted) I don't receive BuildingName
> because ROW_START differs?
> 
> Here is my HistoricalSession query code:
> public <T extends AbstractEntity>T queryByHistory(final Class<T> entity,
> final String uuid, final DateTime time) {
>         
>     ReadObjectQuery query = new ReadObjectQuery(entity);
>    
> query.setSelectionCriteria(query.getExpressionBuilder().get("objectId").equal(uuid));
>     Session historicalSession = 
> this.entityManager.getServerSession().acquireClientSession().acquireHistoricalSession(
>             new AsOfClause(time.getMillis()));
>     return (T) historicalSession.executeQuery(query);
> }
> 
> Can anyone see what's wrong?
> 
> /Daniel
> 


-----
http://wiki.eclipse.org/User:James.sutherland.oracle.com James Sutherland 
http://www.eclipse.org/eclipselink/
 EclipseLink ,  http://www.oracle.com/technology/products/ias/toplink/
TopLink 
Wiki:  http://wiki.eclipse.org/EclipseLink EclipseLink , 
http://wiki.oracle.com/page/TopLink TopLink 
Forums:  http://forums.oracle.com/forums/forum.jspa?forumID=48 TopLink , 
http://www.nabble.com/EclipseLink-f26430.html EclipseLink 
Book:  http://en.wikibooks.org/wiki/Java_Persistence Java Persistence 
-- 
View this message in context: http://old.nabble.com/Configuring-History-Policy-for-%40OneToMany-tp27874092p28004184.html
Sent from the EclipseLink - Users mailing list archive at Nabble.com.



Back to the top