I am a newbie to NHibernate so it is quite possible that I am missing something here.
I am using NHibernate 1.2.0.4.
I was having some problems with a one-many relationship. I have a parent class that contains a few bags, all of which are 1-2-m relations. When I would load my classes, I would get back the correct number of children in the collections, but every child in the collection would be the exact same record.
For example, I have parents A and Z, A has 4 children b,c,d and e and Z has children x and y. When I would look at the collection of children under A, after it was finished loading, I would have b,b,b and b and under Z it would be x and x. Since I could not figure out what was wrong or why NHibernate would include such functionality I decided to download the source and try to figure out what I was missing. I noticed that in the Loader.cs class the GetRow method was where my object was being hydrated. There is a if-else predicate, that determines if the object was already loaded or if it needs to hydrate the new object. I noticed that when I would have a collection of more than 1 child, it would say the object was already loaded and it would not hydrate a new object. I added a line to make sure that it would always return null to force a hydration and once I did that everything worked great. My guess is that it is not hydrating the object because it is using the parent as its key. The parent is obviously going to be loaded already once the first child has been hydrated. This was causing all subsequent children to be returning the record of the first loaded child.
Below is the code I changed to test this:
object obj = null;
EntityKey key = keys[i];
if (keys[i] == null)
{
// do nothing
}
else
{
//If the object is already loaded, return the loaded one
obj = session.GetEntity(key);
obj = null;
if (obj != null)
{
//its already loaded so dont need to hydrate it
InstanceAlreadyLoaded(rs, i, persisters[i], key, obj, lockModes[i], session);
}
else
{
obj =InstanceNotYetLoaded(rs, i, persisters[i], key, lockModes[i], optionalObjectKey, optionalObject, hydratedObjects, session);
}
}
I did not bother to add anything else other than what is in bold because I am not sure of the intended meaning.
What I am wondering is if I am doing something wrong that is causing it to act this way, or if this is a bug in NHibernate.
I will post more information if it is needed, but not unless asked for.
Here is my hbm file:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property">
<class name="Parent" table="parentTable">
<composite-id>
<key-property name="Id" column="ID"/>
<key-property name="Code" column="Seq"/>
</composite-id>
<property name ="ModifiedDate" column="LastUpdated_Date"/>
<bag name="ChildrenA" lazy="false" fetch="subselect" table="childTable">
<key>
<column name="ID"/>
<column name="Seq"/>
</key>
<one-to-many class="ChildA"/>
</bag>
<bag name="ChildrenB" lazy="false" fetch="subselect" table="childTable">
<key>
<column name="Id"/>
<column name="Seq"/>
</key>
<one-to-many class="ChildB"/>
</bag>
</class>
<class name ="ChildA" table="childTable">
<composite-id>
<key-property name="Id" column="Id"/>
<key-property name="SequenceIdentifier" column="Seq"/>
</composite-id>
<property name="FirstName" column="FirstName"/>
<property name="LastName" column="LastName"/>
</class>
<class name ="ChildB" table="childTable">
<composite-id>
<key-property name="Id" column="Id"/>
<key-property name="SequenceIdentifier" column="Seq"/>
</composite-id>
<property name="FirstName" column="FirstName"/>
<property name="LastName" column="LastName"/>
</class>
</hibernate-mapping>
Thanks
|