Reputation: 6679
There are three object entities: GrandParent, Parent and Child
There are four tables: GrandParent, Parent, Child, ParentsChildrenList
Parent and Child are both identified by composite keys.
How should this relationship be mapped? Note that object Child doesn't contain a reference to Parent nor GrandParant, however table Child uses grandParentId as part of its primary key.
This tables structure satisfies the use cases. However, the mapping isn't straight-forward. Any design insight is appreciated.
[--- Update 1 ---]
I added object GrandParent to Child, and created composite key ChildId for mapping to the tables.
The question remains: Can Child borrow a piece of its id from Parent? That way I don't need to introduce GrandParent in Child purely for persistence.
[--- Update 2 ---]
I removed object GrandParent from Child, but kept the ChildId and the method that allows grandParentId to be set. Things still work as expected. I suspect this can't be reduced further.
Upvotes: 2
Views: 1600
Reputation: 1358
To add to what the other post alluded to, creating a custom type allows for much greater flexibility when defining keys. You could also use a custom id type with a single column but add your own custom logic to generate a surrogate key based upon the parameters to the constructor.
Composite Example:
(Child )
public class Child implements java.io.Serializable {
private ChildId id;
....
(ChildId )
public class ChildId implements java.io.Serializable {
private long id;
private long parent_id;
.....
(Child.cfg.xml)
....
<composite-id name="id" class="ChildId">
<key-property name="id" type="long">
<column name="id" />
</key-property>
<key-property name="parent_id" type="long">
<column name="parent_id" />
</key-property>
</composite-id>
.....
usage:
Child c = new Child ();
ChildId cid = new ChildId(null,1);
c.setId(cid);
session.save(c);
Creating a custom type allows for alot of customization that is tightly coupled with ORM vs building a solution into the application layer.
Upvotes: 0
Reputation: 120278
The most immediate insight I have is do what hibernate recommends, use surrogate keys. This means every class has a single id for persistence purposes only. You can still map the natural keys. Otherwise you are really fighting the framework, and you are not going to be happy.
That said, a team I was on solved this problem by creating a custom type for the id, where one of the parts was assigned and was was generated.
This might also be helpful http://opensource.atlassian.com/projects/hibernate/browse/HHH-2060
Upvotes: 2