-->
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: Using fetch="join" and expected behaviour?
PostPosted: Mon Mar 12, 2007 5:17 pm 
Newbie

Joined: Mon Mar 12, 2007 2:47 pm
Posts: 11
I've recently had issues with performance with getting a list of Objects which has as one of it's properties a Set of other objects. Essentially, our Banner class has a Set of bannerClickHistory objects which is a one-to-many mapping. When i go and grab a list of banners, i would also retrieve a set of bannerclickhistory objects. The problem i've encountered, is that over time as the number of rows grows in the Banner table with associated bannerclickhistory, it was taking almost up to 5 minutes to grab a collection of even 100 banner objects. I've turned on the show_sql = true flag, and now have noticed that the Hibernate SQL seems to generate an HSQL statement for getting the bannerclickhistory for every banner object (parent) that is fetched (resulting in 99 additional child calls). I thought that setting the fetch="join" in the parent .hbm file would do the trick to narrow down the number of queries by doing a join but it doesn't seem to do what i was exepecting. Is there something I'm missing or is my interpretation of this fetch="join" not correct? Thanks for any help. I have a sample of the mapping file and the execution code down below.

Hibernate version: 3.2.0

Name and version of the database you are using: Postgres 7.4


Mapping file for the banner
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 10-Aug-2006 12:24:19 PM by Hibernate Tools 3.2.0.beta6a -->
<hibernate-mapping>
    <class name="com.gdi.mms.businessobjects.Banner" table="banner">
        <id name="id" type="int">
            <column name="bannerkey" />
         <generator class="sequence">
            <param name="sequence">banner_id_seq</param>
         </generator>
        </id>

        <property name="licenseeid" type="int">
            <column name="licenseekey" not-null="true" />
        </property>

      
   <set name="bannerClickHistory" inverse="true" lazy="false" fetch="select">
            <key>
                <column name="BannerKey" not-null="true" />
            </key>
            <one-to-many class="com.gdi.mms.businessobjects.BannerClickHistory" />
        </set> 
      
    </class>
</hibernate-mapping>


java code making the call, the call ends up querying for 3 Banner items in the list... and the HSQL shows that 3 calls were made to the bannerClickHistory for each banner. (this is the part where i'm wondering how do you join if even possible)
Code:
            System.out.println("starting now....");
            long startTime = System.currentTimeMillis();
           
            tx = session.getTransaction();
            tx.begin();

            Query query = session.createQuery("from Banner where licenseeid = 445");           

            resultList = query.list();

            tx.commit();           
           
            long endTime = System.currentTimeMillis();           
            System.out.println("All done getting banner list size of :  " + resultList.size());
            System.out.println("Execution time for this is:  " + (endTime - startTime));



The HSQL output
Code:
starting now....
Hibernate: select banner0_.bannerkey as bannerkey19_, banner0_.licenseekey as licensee2_19_ from banner banner0_ where banner0_.licenseekey=445
Hibernate: select bannerclic0_.BannerKey as BannerKey1_, bannerclic0_.bannerclickhistorykey as bannercl1_1_, bannerclic0_.bannerclickhistorykey as bannercl1_22_0_, bannerclic0_.BannerKey as BannerKey22_0_, bannerclic0_.CreationDate as Creation3_22_0_ from BannerClickHistory bannerclic0_ where bannerclic0_.BannerKey=?
Hibernate: select bannerclic0_.BannerKey as BannerKey1_, bannerclic0_.bannerclickhistorykey as bannercl1_1_, bannerclic0_.bannerclickhistorykey as bannercl1_22_0_, bannerclic0_.BannerKey as BannerKey22_0_, bannerclic0_.CreationDate as Creation3_22_0_ from BannerClickHistory bannerclic0_ where bannerclic0_.BannerKey=?
Hibernate: select bannerclic0_.BannerKey as BannerKey1_, bannerclic0_.bannerclickhistorykey as bannercl1_1_, bannerclic0_.bannerclickhistorykey as bannercl1_22_0_, bannerclic0_.BannerKey as BannerKey22_0_, bannerclic0_.CreationDate as Creation3_22_0_ from BannerClickHistory bannerclic0_ where bannerclic0_.BannerKey=?
All done getting banner list size of :  3
Execution time for this is:  360


Top
 Profile  
 
 Post subject: Re: Using fetch="join" and expected behaviour?
PostPosted: Tue Mar 13, 2007 1:14 am 
Newbie

Joined: Mon Oct 10, 2005 6:10 am
Posts: 10
try this: fetch="join".
Quote:
<set name="bannerClickHistory" inverse="true" lazy="false" fetch="select">


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 13, 2007 12:44 pm 
Newbie

Joined: Mon Mar 12, 2007 2:47 pm
Posts: 11
Oops.. my mistake.. i pasted an old version of the hbm.xml file... my latest one does have fetch="join" in it... however hibernate still seems to ignore my mapping metadata setting....


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 13, 2007 12:54 pm 
Newbie

Joined: Mon Mar 12, 2007 2:47 pm
Posts: 11
I stumbled upon one thead that pointed to the Hibernate Users FAQ at http://hibernate.org/117.html and i found the entry ... Hibernate ignores my outer-join="true" or fetch="join" setting and fetch an association lazily, usering N+1 selects!

So after reading that i decided to modify my code a little and instead using criteria and actually using the .setFetchMode("bannerClickHistory", FetchMode.JOIN) to make my queries... this seem to have done the trick as i see only one Hibernate HSQL that contains a join query instead of N+1 selects! However I ran into another problem, where i was required to do add a Restriction into the query for a property that is in the Set of bannerClickHistory. Hibernate didn't like the idea of me doing something like.... .add(Restrictions.eq("bannerClickHistory.typeID", 1000)) as it would complain that the typeID property is not found. I then ran across a couple threads talking about using createAlias. That seem to have done the trick and now I can actually filter on that Set property, however now hibernate goes back to the original problem of not doing a join again. It seems as if it's now doing multiple queries cuz of the Alias defined. Am i suppose to apply a .setFetchMode to the Alias as well?

Thanks for any help


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 13, 2007 3:06 pm 
Expert
Expert

Joined: Tue Jul 11, 2006 10:21 am
Posts: 457
Location: Columbus, Ohio
You can specify the join type on the createAlias method. e.g.
Code:
...createAlias("bannerClickHistory", "history", CriteriaSpecification.LEFT_JOIN)


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.