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.  [ 4 posts ] 
Author Message
 Post subject: fetch="join" behavior
PostPosted: Fri Oct 16, 2009 12:51 pm 
Newbie

Joined: Fri Oct 16, 2009 12:27 pm
Posts: 7
Hi, I am having a strange issue that is probably a simple configuration change, but I can't figure it out. Here is the scenario:
I have 2 objects: an Individual and IndividualAddress, where the Individual contains a collection of IndividualAddress objects. So for example, I have a single individual who has 1 or more addresses.
The relationship is expressed in the hbm as:
<class name="IndividualDTO" mutable="false" table="DCS2000.TBL_SUBR_INDV">
<composite-id>
<key-property name="SubrId">
<column name="SUBR_ID" sql-type="varchar" length="30" not-null="true"/>
</key-property>
<key-property name="IndvId">
<column name="INDV_ID" sql-type="number" length="2" not-null="true"/>
</key-property>
</composite-id>
<property name="SubrId" column="SUBR_ID"/>
<property name="IndvId" column="INDV_ID"/>
<property name="LastName" column="LNME"/>
<property name="FirstName" column="FNME"/>
<property name="DOB" column="DOB"/>
<property name="SSN" column="SSN"/>
<bag name="IndividualAddressList" access="property" table="TBL_SUBR_INDV_ADDR" lazy="false" fetch="join" inverse="true" cascade="all">
<key>
<column name="SUBR_ID"/>
<column name="INDV_ID"/>
</key>
<one-to-many class="IndividualAddressDTO"/>
</bag>
</class>
<class name="IndividualAddressDTO" table="DCS2000.TBL_SUBR_INDV_ADDR">
<composite-id>
<key-property name="SubrId">
<column name="SUBR_ID" sql-type="varchar" length="30" not-null="true"/>
</key-property>
<key-property name="IndvId">
<column name="INDV_ID" sql-type="number" length="2" not-null="true"/>
</key-property>
<key-property name="AddrCode">
<column name="ADDR_CDE" sql-type="number" length="2" not-null="true"/>
</key-property>
</composite-id>
<property name="SubrId" column="SUBR_ID"/>
<property name="IndvId" column="INDV_ID"/>
<property name="Addr1" column="ADDR1"/>
<property name="Addr2" column="ADDR2"/>
<property name="Addr3" column="ADDR3"/>
<property name="City" column="CITY"/>
<property name="State" column="STATE"/>
<property name="Zip" column="ZIP"/>
<property name="CountryCode" column="COUNTRY_CDE"/>
<many-to-one name="Individual" access="property" class="IndividualDTO" lazy="proxy">
<column name="SUBR_ID"/>
<column name="INDV_ID"/>
</many-to-one>
</class>


I originally did not include the fetch attribute in the bag element and I believe it defaults to fetch="select". When I executed the map this way I would get what I would expect object wise; meaning that I would get an Individual with a collection of IndividualAddress objects. In the course of looking at tweaking performance I noticed in the logs that the sql being generated was not doing a join, it was merely selecting the Individual object and then doing an additional select for each IndividualAddress in the collection. So if I had 1 Individual with 3 IndividualAddress objects, 4 sql statements were executed; 1 to get the Individual and 3 to get each IndividualAddress. Looking at time spent, it amounted to some really poor performance.
So after some research (knowing I wanted to do a join), I came across the fetch="join" attribute and implemented that. Now I was getting the single sql statement I wanted for performance, but I was also getting multiple Individual objects when I should only be getting 1. From an sql perspective it made sense; each Individual record would be duplicated for every IndividualAddress record, but I thought NHibernate would be smart enough to eliminate the duplicate records and roll it up into 1 with a collection (as it properly did when the fetch attribute set to sequential select).

Sorry for the long winded question, but what am I doing wrong? I suspect it is something simple, but I have not been able to come up with a work around to this issue. I am concerned that this may be a byproduct of using composite keys or not implementing them correctly. Any help would be greatly appreciated.

thanks in advance

-matt


Top
 Profile  
 
 Post subject: Re: fetch="join" behavior
PostPosted: Tue Oct 20, 2009 7:26 am 
Newbie

Joined: Fri Oct 16, 2009 12:27 pm
Posts: 7
bump!

Anyone?


Top
 Profile  
 
 Post subject: Re: fetch="join" behavior
PostPosted: Tue Oct 20, 2009 8:34 am 
Expert
Expert

Joined: Thu Dec 14, 2006 5:57 am
Posts: 1185
Location: Zurich, Switzerland
That behaviour is by design. If you retrieve the objects with a criteria, you have to add a resultset transformer:

.SetResultTransformer( CriteriaUtil.DistinctRootEntity )

if you use a HQL query, I think a "select distinct ..." does the trick.

_________________
--Wolfgang


Top
 Profile  
 
 Post subject: Re: fetch="join" behavior
PostPosted: Tue Oct 20, 2009 9:22 am 
Newbie

Joined: Fri Oct 16, 2009 12:27 pm
Posts: 7
wolli wrote:
That behaviour is by design. If you retrieve the objects with a criteria, you have to add a resultset transformer:

.SetResultTransformer( CriteriaUtil.DistinctRootEntity )



Thank you very much, that was exactly what I needed.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 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.