-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: Temporal modeling / OneToMany in Embeddable
PostPosted: Fri May 06, 2016 9:51 am 
Newbie

Joined: Thu May 05, 2016 4:34 pm
Posts: 2
I'm trying to create a temporal model where an Employee entity contains a collection of EmployeeDetails. Each EmployeeDetails is marked with dates validFrom and a validTo so I can keep track of an employee's name changes over time. To prevent an employee from having multiple names at the same point in time I have created a NoOverlap constraint and placed it on the EmployeeDetails collection. Later on I am planning to add Envers on top of this so I can keep track of when the an employee officially changed her name and when the new name was entered into the application.

Example 1:

Code:
@Entity
public class Employee {
   // Things left out for brevity

   @Version
   private long version;

   @ElementCollection
   @NoOverlap // <- Custom constraint
   private List<EmployeeDetails> details;
}

@Embeddable
public class EmployeeDetails {
   // Things left out for brevity
   
   private Date validFrom;
   private Date validTo;
   private String name;
}


In example 1 everything works great. Adding a new EmployeeDetails to the collection triggers a validation of the Employee which prevents overlapping entries. Modifying an existing EmployeeDetails also triggers a validation of the Employee which again prevents overlapping entries.

Example 2:

Code:
@Embeddable
public class EmployeeDetails {
   // Things left out for brevity
   
   private Date validFrom;
   private Date validTo;
   private String name;
   @ManyToOne
   private Department department;
}


In example 2 I have added support for tracking which deparment an employee is working in. This also works great.

Example 3:

Code:
@Embeddable
public class EmployeeDetails {
   // Things left out for brevity
   
   private Date validFrom;
   private Date validTo;
   private String name;
   @ManyToOne
   private Department department;
   @OneToMany
   private List<Project> projects;
}


In example 3 I have added support for tracking which projects an employee is a member of. Unfortunately Hibernate won't start at all with this configuration due to a bug that was reported eight years ago. See issue https://hibernate.atlassian.net/browse/HHH-4313. I wish this would be fixed but it's way beoynd my skills to submit a patch for it. The suggested workaround is to model the embeddable as an entity instread.

Example 4:

Code:
@Entity
public class Employee {
   // Things left out for brevity

   @Version
   private long version;

   @OneToMany
   @NoOverlap // <- Custom constraint
   private List<EmployeeDetails> details;
}

@Entity
public class EmployeeDetails {
   // Things left out for brevity
   
   private Date validFrom;
   private Date validTo;
   private String name;
}


In example 4 adding a new EmployeeDetails to the collection triggers a validation of the Employee which prevents overlapping entries. But modifying an existing EmployeeDetails does not trigger a validation of the Employee. This unfortunately makes it possible to create overlapping entries.

I've tried to solve this with various approaches such as implementing a custom TraversableResolver in Hibernate Validator, creating a Hibernate Interceptor and overriding the findDirty method, by implementing a CustomEntityDirtinessStrategy and finally by making all my entities immutable in order to prevent modifications of existing entities.

None of these approaches have worked really well and all come with even more complicated drawbacks. I believe some of the approaches listed above could work but I get lost in the Hibernate internals when trying to find a working solution. Is there any hope of someone fixing HHH-4313? Does anyone have an example of modified TraversableResolver or a custom dirty checking algorithm that could work for this situation?

I have very small maven project with an entity/embeddable-model and an entity/entity-model side-by-side and a complete set of unit tests that I will happily make avaialble to anyone willing to give this a try. Just tell me where to post it. :)


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.