-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 
Author Message
 Post subject: Question for the NHibernate team
PostPosted: Fri Jul 20, 2007 12:21 pm 
Newbie

Joined: Mon Jul 16, 2007 5:38 pm
Posts: 9
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


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 20, 2007 12:27 pm 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
You probably have your entities mapped incorrectly. NHibernate seems to think all the children have the same ID while in fact they do not.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 20, 2007 12:28 pm 
Newbie

Joined: Mon Jul 16, 2007 5:38 pm
Posts: 9
I just posted my hbm file above, if you need to look at it.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 20, 2007 1:23 pm 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
Eh, you have both ChildrenA and ChildrenB in the same table? And both ChildA and ChildB mapped to the same table? No wonder NHibernate gets confused.

And <key> column should be the foreign key column (from childTable to parentTable).

It's certainly good that you are not afraid to dig into NHibernate internals, but you should study the available documentation first, it will save you some time at this stage.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 23, 2007 8:33 am 
Regular
Regular

Joined: Wed Apr 25, 2007 4:18 am
Posts: 51
Location: Belarus, Gomel
Hi turtlestang00!

How does the DB tables look like? How does they relate to each other?

From your mapping it is not clear - you have the same DB fields as children PK and parent PK - so for children table it seems that you have PK=FK - this means that you can't have "many" children - moreover you can't even have BOTH ChildA and ChildB - as there will be always exactly ONE instance from children table for given id+seq.
I bet your mapping is incorrect - you map foreign key as composite-id, but you real PK is bigger - and must include some additional columns, to distinguish between b,c,d and e rows that have the same id+seq...
Moreover, you'd better use simple (surrogate) PK's for your tables (if you can change DB model of course) - it is much simplier.

_________________
WBR, Igor


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.