Candy Chiu
Candy Chiu

Reputation: 6679

Mapping parent child relationship - composite key formed by fields of two objects

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

Answers (2)

ebt
ebt

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

hvgotcodes
hvgotcodes

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

Related Questions