After a couple of days of duel with so many varieties of settings, I realized that my settings have less to do but more with how I am saving my parent and children.
I found that in my bi-directional mapping (parent has a collection list of children and child has a reference of parent) and using Cascade="all-delete-orphan" to be able to add, update and delete children on equivalent changes to parent along with inverse="true" (not sure if how I am using it!).
The problem was that I have been trying to achieve this in two WRONG ways.
1) Creating a parent object first, (obviously not saving it) meaning it does not have the primary key yet. I then created a separate list of children and here was the problem, the parent reference was not included, i.e.,
child.setParent(parentObj) was not included when creating this list of children. I thought that as the parentObj was not persisted yet so it does not make much sense to do that. But I was wrong.
children.add(child);
Anyways, once I created a list of these child objects, I then do a parentObj.setChildren(chidren) and to save both parent and children I can just do session.save(parentObj).
2) I also tried saving parent first, get its object, then followed by saving the children as I have the the parent object stored in each child (bi-directional and child has a reference to parent object) while saving each of the child objects as child.setParent(parentObj).
Problem:
In the first case, it would not save the parent FK in the children. In the second case, where I was saving parent first followed by children, I am using child.setParent(parentObj) only after session.save(parentObj) and so successfully able to insert data into my tables, because I was saving the parent first followed by a individual child entries using a reference of the saved parent object. Note that both were separately done.
However, right after doing this, running a query somewhere later in my application, to access this parent using a brand new query to fetch the parent by its primary key session.find(parent.class,id) and accessing its children using
parentObj.getChildren() gives an empty list although I can see children populated in the child table with the correct parent FK.
Hibernate is somehow getting me the data from its cache I believe, otherwise it should get me all the children AS there are entries in the child table for the given parent FK but it does not as I have already defined how my parent and children are related in my parent.hbm.xml
Is there any thing that can force hibernate to look up or do a fresh load of the parent object and may be it will then include children as well?
Solution: If I save the parent and children by just one session.save(parent) after adding the child collection to parent as parent.setChildren(children) where the children, each had a reference to the parent obj child.setParent(parentObj), I have no problems running a query somwhere later in my application session.find(parent.class,id) and accessing the childCollection eagerly by parentObj.getChildren().
Cameron McKenzie
I will surely look into your inputs and suggestions. Sorry I was more eager to post that I have a working solution to my problem.
-Thanks
Krishna
Parent.hbm.xml
Code:
<id name="someId" type="java.lang.Long">
<column name="SOME_ID" precision="11" scale="0" />
<generator class="increment" />
</id>
<list name="Children" cascade="all-delete-orphan"
inverse="true" lazy="false">
<key column="SOME_ID" />
<list-index column="SOME_SEQNO" base="1"/>
<one-to-many class="Child" />
</list>
Child.hbm.xml
Code:
<id name="ChildId" type="java.lang.Long">
<column name="CHILD_ID" precision="11" scale="0" unique="true" not-null="true"/>
<generator class="increment" />
</id>
<many-to-one name="parent" column="SOME_ID" class="Parent"
unique="true" cascade="all" />
I am unable to eagerly load the child list as
Code:
Session session = getSessionInstance();
try {
Parent instance = (Parent ) session.get(Parent .class,
someId);
return instance;
} catch (RuntimeException re) {
re.printStackTrace();
throw re;
}