-->
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.  [ 6 posts ] 
Author Message
 Post subject: Duplicate entries with eager loaded collections
PostPosted: Mon Dec 05, 2005 9:42 am 
Newbie

Joined: Thu Dec 01, 2005 1:49 pm
Posts: 2
Hello,

My name is Christian Sprajc and I'm working for a software company which creates logistics software (http://www.riege.com). Currently we migrate our persistence layer from ejb2 to Hibernate. In this process we discoverd a strange bug in the eager loading of collections.
We like Hibernate, because it greatly simplifies our O/R-Mapping.
We have to use Eager initalizing of Collections, because the Objects returned from hibernate are getting moved to the client over RMI.

Here is a detailed description of our problem:

Hibernate version:
Hibernate & Hibernate Annotation from CVS (Date: 5th, Dec, 2005)

Code between sessionFactory.openSession() and session.close():
Criteria c = getHibernateSession().createCriteria(TaxCode.class);
c.list();

Name and version of the database you are using:
Oracle 10i

Scenario description:

1) We have the following object model:
TaxCode <-1-------N-> TaxRates
A TaxCode can have multiple TaxRate

TaxRates are a simple eager initalized collection in TaxCode:
Excerpt from Class TaxRate:

...
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
public Collection<TaxRate> getTaxRates() {
return taxRates;
}
...

Database content:
We have five (5) TaxCodes in database.
Three (3) of them have exactly one (1) TaxRate, which means the other two (2) TaxCodes have no TaxRates in their list.

The generated SQL (show_sql=true):

select this_.ASAP_OID as ASAP1_55_1_, this_.changeTime as changeTime55_1_, this_.changeUser as changeUser55_1_, this_.version as version55_1_, this_.companyOrgUnitOid as companyO5_55_1_, this_.countryOrgUnitOid as countryO6_55_1_, this_.branchOrgUnitOid as branchOr7_55_1_, this_.createOrgUnitOid as createOr8_55_1_, this_.code as code55_1_, this_.name as name55_1_, this_.validFrom as validFrom55_1_, this_.validTo as validTo55_1_, this_.presetting as presetting55_1_, this_.taxable as taxable55_1_, taxrates2_.TaxCode_ASAP_OID as TaxCode1_3_, taxrate3_.ASAP_OID as taxRates2_3_, taxrate3_.ASAP_OID as ASAP1_56_0_, taxrate3_.changeTime as changeTime56_0_, taxrate3_.changeUser as changeUser56_0_, taxrate3_.version as version56_0_, taxrate3_.rate as rate56_0_, taxrate3_.validFrom as validFrom56_0_ from TaxCode this_ left outer join TaxCode_TaxRate taxrates2_ on this_.ASAP_OID=taxrates2_.TaxCode_ASAP_OID left outer join TaxRate taxrate3_ on taxrates2_.taxRates_ASAP_OID=taxrate3_.ASAP_OID

Problem description:
The problem occours when we switch the Collection of TaxRate (getTaxRates) to eager loading.
When executing a findAll on the TaxCodes table (see "Code between sessionFactory.openSession() and session.close()") the returned collection contains eight (8) elements! Three (3) of them are actually duplicate entries of the same TaxCode.

The correct result should be five (5) TaxCodes in the collection.

The strange thing happends when changing the getTaxRates() collection on TaxCode to Lazy loading.
The returned list returned by the Critiera object (see "Code between sessionFactory.openSession() and session.close()") contains the expected five (5) results of TaxCode.

We are looking forward to hear from anyone who can help.

Best regards,
Christian Sprajc


Top
 Profile  
 
 Post subject: Re: Duplicate entries with eager loaded collections
PostPosted: Mon Dec 05, 2005 9:59 am 
Newbie

Joined: Thu Dec 01, 2005 1:49 pm
Posts: 2
There was a typo in my post:
The Excerpt is from Class TaxCode not TaxRate of course!

totmacher wrote:
TaxRates are a simple eager initalized collection in TaxCode:
Excerpt from Class TaxRate:

...
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
public Collection<TaxRate> getTaxRates() {
return taxRates;
}
...


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 16, 2005 10:36 pm 
Newbie

Joined: Sat Oct 22, 2005 6:28 pm
Posts: 1
This is because when you eagerly fetch a collection in Hibernate it returns one object for each element in the collection (just like the query would do in a similar SQL SELECT)

From Hibernate in Action page 262:
Quote:
If you fetch a collection, Hibernate doesn’t return a distinct result list. For exam-
ple, an individual Item might appear several times in the result List, if you
outer-join fetch the bids. You’ll probably need to make the results distinct
yourself using, for example: distinctResults = new HashSet(resultList);.
A Set doesn’t allow duplicate elements.


Top
 Profile  
 
 Post subject: Re: Duplicate entries with eager loaded collections
PostPosted: Wed Jan 11, 2006 9:58 am 
Newbie

Joined: Wed Jan 11, 2006 9:02 am
Posts: 11
Ok RedHatDude I read this point in the book too, but it would be possibe other solution to it.

Something like this:
Code:

Criteria c = getHibernateSession().createCriteria(TaxCode.class);
c.ListDistinct();



Thanks,
Cleiton


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 11, 2006 10:27 am 
Newbie

Joined: Sun Oct 09, 2005 6:36 am
Posts: 19
Adding the read objects to a (Hash)Set is not the best idea, especilly if you need them in some defined order. A much better idea would be to use something that Hibernate already provides:

loCriteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);


Top
 Profile  
 
 Post subject: Re: Duplicate entries with eager loaded collections
PostPosted: Wed Jan 11, 2006 10:46 am 
Newbie

Joined: Wed Jan 11, 2006 9:02 am
Posts: 11
Thanks ekupcik! That's it!

Cleiton


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