-->
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: poor performance many-to-many query execution
PostPosted: Fri Sep 05, 2003 1:03 pm 
before beginning, just let me say thanks gavin for all the help you've given me. i've been piling up my questions over the past few days i've been unable to find answers to and you've been most helpful.

this one is probably something stupid i'm doing, but i can't for the life of me figure out what. we have a many-to-many association that looks like this in our DB:

Code:
BUSINESS        <-> BUSINESS_CATEGORY <-> CATEGORY
BUSINESS_ID         BUSINESS_ID           CATEGORY_ID
                    CATEGORY_ID


extremely simple. i have defined the set in the business class like this:

Code:
<set      name="categories"
          lazy="true"
       inverse="false"
       cascade="none"
         table="BUSINESS_CATEGORY">
      <key  column="BUSINESS_ID" />
      <many-to-many
        column="CATEGORY_ID"
         class="com.sa.go.bto.Category" />
</set>


it is not a bidirectional association, so you cannot get the businesses in a category. now, when i execute a business.getCategories() i get queries like this:

Code:
Hibernate: select business0_.CATEGORY_ID as CATEGORY2___, business0_.BUSINESS_ID as BUSINESS1___ from BUSINESS_CATEGORY business0_ where business0_.BUSINESS_ID=?
Hibernate: select category0_.CATEGORY_ID as CATEGORY_ID0_, category0_.CATEGORY_NAME as CATEGORY2_0_, category0_.CATEGORY_DESC as CATEGORY3_0_, category0_.PARENT_ID as PARENT_ID0_ from CATEGORY category0_ where category0_.CATEGORY_ID=?
Hibernate: select category0_.CATEGORY_ID as CATEGORY_ID0_, category0_.CATEGORY_NAME as CATEGORY2_0_, category0_.CATEGORY_DESC as CATEGORY3_0_, category0_.PARENT_ID as PARENT_ID0_ from CATEGORY category0_ where category0_.CATEGORY_ID=?


in other words, it first pulls back all the CATEGORY_ID values from the BUSINESS_CATEGORY table and then issues a select for each record it finds against CATEGORY. it would be much faster to resolve the values with a single select like:

Code:
select c.*
  from business_category bc,
       category c
where bc.business_id = ? and bc.category_id = c.category_id


is there any way to tweak the configuration to do that?

thanks again!
james


Top
  
 
 Post subject:
PostPosted: Fri Sep 05, 2003 1:16 pm 
Beginner
Beginner

Joined: Thu Sep 04, 2003 2:50 pm
Posts: 45
Location: US: New York NY
maybe a stupid question, but did you set hibernate to use outer join?

hibernate.use_outer_join true

in hibernate.properties


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 05, 2003 1:29 pm 
russellsimpkins wrote:
maybe a stupid question, but did you set hibernate to use outer join?

hibernate.use_outer_join true

in hibernate.properties


sure did :-)


Top
  
 
 Post subject:
PostPosted: Fri Sep 05, 2003 9:21 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
In recent releases of Hibernate (forget which one) there is an outer-join attribute on the collection mappings.


However, it is MUCH better to not enable this in the mapping file! Collections should be lazy.


Instead use a HQL LEFT JOIN FETCH when you want to use the collection. (Or a Criteria.setFetchMode() ).


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 08, 2003 9:25 am 
gavin wrote:
Instead use a HQL LEFT JOIN FETCH when you want to use the collection. (Or a Criteria.setFetchMode() ).


i attempted to use the HQL LEFT JOIN FETCH and got some weird results. for the many-to-many business to category relationship, hibernate generated the query down below. the "Amtrak" business has 3 categories associated with it, so the query brings back 3 records. unfortunately, hibernate does not recognize that the three records are 1 amtrak business with 3 distinct categories. instead, i get 3 Business objects back and each of those objects is associated to 1 Category object. any idea why? here's the HQL query:

Code:
select distinct business
  from com.sa.go.bto.Business as business
       left join fetch business.categories as category
       inner join business.locations as location
where (business.nationalFlag = YES or
       location.class = com.sa.go.bto.OnlineBusinessLocation)


and the SQL it generated:

Code:
select distinct business0_.BUSINESS_ID as BUSINESS_ID0_, category2_.CATEGORY_ID as CATEGORY_ID1_, business0_.BUSINESS_NAME as BUSINESS2_0_, business0_.NATIONAL_FLAG as NATIONAL3_0_, business0_.PJP_FLAG as PJP_FLAG0_, (SELECT COUNT(*)                        FROM STORE_LOCATION SC                       WHERE SC.STORE_LOCATION_TYPE_ID = 1 AND                             SC.BUSINESS_ID = business0_.BUSINESS_ID) as f0_0_, (SELECT COUNT(*)                        FROM STORE_LOCATION SC                       WHERE SC.STORE_LOCATION_TYPE_ID = 2 AND                             SC.BUSINESS_ID = business0_.BUSINESS_ID) as f1_0_, category2_.CATEGORY_NAME as CATEGORY2_1_, category2_.CATEGORY_DESC as CATEGORY3_1_, category2_.PARENT_ID as PARENT_ID1_, categori1_.CATEGORY_ID as CATEGORY2___, categori1_.BUSINESS_ID as BUSINESS1___ from BUSINESS business0_, BUSINESS_CATEGORY categori1_, CATEGORY category2_, STORE_LOCATION location3_ where business0_.BUSINESS_ID=categori1_.BUSINESS_ID(+) and categori1_.CATEGORY_ID=category2_.CATEGORY_ID(+) and business0_.BUSINESS_ID=location3_.BUSINESS_ID and (((business0_.NATIONAL_FLAG='Y' )or(location3_.STORE_LOCATION_TYPE_ID=1 )))


Top
  
 
 Post subject:
PostPosted: Mon Sep 08, 2003 9:57 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
hibernate does not recognize that the three records are 1 amtrak business

Wrong! It just gives you back the same object three times. This is by design.

You can distinctify the results your self. (In 2.1 you can use the uniqueResult() method if you like)


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.