Search code examples
hibernatecomposite-key

Hibernate - automatically assign foreign key to child?


Ok, so I have 2 objects, Parent and Child. The child basically looks like this:

public class Child implements Serializable 
{

    // primary (composite) key
    private int parentId;
    private String name;

    // random value
    private String val;

    public Child(String name, String val) {
        this.name = name;
        this.val = val;
        // note: parentId is not assigned a value
    }

    public void setParentId(int id) {

    [...]
}

What I want is basically for hibernate to automatically set the parent id of the Child once a Parent object is created. Is this possible or do I have to add child objects to the parent object after the parent object has been saved to the database?

The xml mapping of the parent looks as such:

`<map name="children" inverse="true" lazy="true" cascade="all,delete-orphan">
    <cache usage="nonstrict-read-write"/>
    <key column="parent_id"/>
    <index column="child_name" type="string"/>
    <one-to-many class="myPack.Child"/>
</map>`

and the xml of the child:

<hibernate-mapping package="myPack">

    <class name="Child" table="child_tbl" lazy="true">

        <composite-id>
            <key-property name="ParentId" type="int" column="parent_id"/>
            <key-property name="Name" column="name" type="string"/>
        </composite-id>

        <property name="Val" blablabla
[...]

Solution

  • When you want hibernate to insert parent-child together with a foreign key use object mapping rather than ids.

    Lets take an example from here,

    public class AMain {
     
     //Properties of A.
     List<ASub3> subList;
    .....
    }
    
    public class ASub3 {
     .....  
     AMain parent;
     .....
    }
    

    in the hbm.xml file in AMain add,

        <list name="subList" inverse="true" cascade="all" lazy="false">
             <key column="a_id" />
             <list-index column="as3_id" />
             <one-to-many class="com.manu.hibernate.mappings.domain.ASub3" />
        </list>
    

    in Asub3 add,

    <many-to-one name="parent" class="com.manu.hibernate.mappings.domain.AMain" 
    column="a_id" unique="true" cascade="save-update" />
    

    Now, in the client code use the beans as below,

         AMain a = new AMain("A");
         ASub3 as3a = new ASub3("List - 1");
         ASub3 as3b = new ASub3("List - 2");
         ASub3 as3c = new ASub3("List - 3");
         as3a.setParent(a);
         as3b.setParent(a);
         as3c.setParent(a);
         List<ASub3> subList = new ArrayList<ASub3>();
         subList.add(as3a);
         subList.add(as3b);
         subList.add(as3c);
    
         a.setSubList(subList);
    

    Now, if youn save AMain both AMain and ASub3 will be updated(I mean corresponding table) with a foreign key to AMain.