-->
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.  [ 3 posts ] 
Author Message
 Post subject: How to avoid fetching unnecessary data via HQL
PostPosted: Tue Aug 04, 2009 3:23 pm 
Beginner
Beginner

Joined: Thu Apr 12, 2007 10:43 am
Posts: 21
Location: Brazil
Hi all,

I've been using Hibernate for the past two and a half years with great results, but there's something that's been bugging me for a long time now: why I can't get Hibernate to avoid fetching unnecessary data via HQL. Let's say I have the following tables:

Country: ID (PK), Description
Maker: ID (PK), Description, Country ID (FK)
Disk: ID (PK), Description, Maker ID (FK)
Computer: ID (PK), Description, Disk ID (FK)

So, every table has a numeric ID as its primary key, and Maker, Disk and Computer all contain foreign keys.

Country is mapped as follows:

Code:
<hibernate-mapping>
<class name="testdb.Country" table="country">
  <id column="country_id" name="id" unsaved-value="none">
   <generator class="assigned"/>
  </id>
  <property column="country_description" name="description"/>
</class>
</hibernate-mapping>


Maker is mapped as follows:

Code:
<hibernate-mapping>
<class name="testdb.Maker" table="maker">
  <id column="maker_id" name="id" unsaved-value="none">
   <generator class="assigned"/>
  </id>
  <property column="maker_description" name="description"/>
  <many-to-one column="country_id" fetch="join"
    name="country" not-found="ignore"/>
</class>
</hibernate-mapping>


(The mappings for Disk and Computer are very similar to that of Maker).

Now, if I try to list() the Computer table with the code below:

Code:
List<Computer> computers = (List<Computer>) listRecordsViaHql(
   "SELECT comp " +
   "FROM   Computer comp " +
   "         LEFT JOIN FETCH comp.disk ");


The following SQL query is generated by Hibernate:

Code:
select computer0_.computer_id          as computer1_3_0_,
       disk1_.disk_id                  as disk1_2_1_,
       computer0_.computer_description as computer2_3_0_,
       computer0_.disk_id              as disk3_3_0_,
       disk1_.disk_description         as disk2_2_1_,
       disk1_.maker_id                 as maker3_2_1_
from computer computer0_
left outer join disk disk1_ on computer0_.disk_id = disk1_.disk_id


Which is fine. However, Hibernate generates a few extra SQL queries to fetch the Maker for every Disk:

Code:
select maker0_.maker_id              as maker1_1_1_,
       maker0_.maker_description     as maker2_1_1_,
       maker0_.country_id            as country3_1_1_,
       country1_.country_id          as country1_0_0_,
       country1_.country_description as country2_0_0_
  from maker maker0_
  left outer join country country1_ on maker0_.country_id =
                                       country1_.country_id
where maker0_.maker_id = ?


Which I don't want Hibernate to do, since I'm not calling computer.getDisk().getMaker() in any point of my code. Aside from using "LEFT JOIN FETCH comp.disk.maker" in my HQL queries or using the Criteria API with max_fetch_depth set to high values, what should I do in order to keep Hibernate from generating these extra queries? I've created my test case with Hibernate 3.3.2, HSQLDB 1.8.0.10 and JDK 1.6.14. Any and all help on this issue would be greatly appreciated. Thanks,

Roger


Top
 Profile  
 
 Post subject: Re: How to avoid fetching unnecessary data via HQL
PostPosted: Wed Aug 05, 2009 12:33 am 
Regular
Regular

Joined: Thu Sep 06, 2007 2:22 am
Posts: 108
Location: Noida,India
This is happening do the mapping between Disk and Marker.
As you told that you are mapping between Disk and Marker like this -
Quote:
<many-to-one column="marker_id" fetch="join"
name="country" not-found="ignore"/>


because you are using fetch = "join", so whenever you will access Disk, Maker will fetch eagerly.

Pay some attention on https://www.hibernate.org/315.html


Top
 Profile  
 
 Post subject: Re: How to avoid fetching unnecessary data via HQL
PostPosted: Wed Aug 05, 2009 8:05 am 
Beginner
Beginner

Joined: Thu Apr 12, 2007 10:43 am
Posts: 21
Location: Brazil
Hi parmendratyagi,

Thanks for taking the time to look at my problem. I had already looked several times through the documentation you pointed out, and had already tried experimentations without using [fetch="join"]:

Code:
<many-to-one column="maker_id" name="maker" not-found="ignore"/>


Unfortunately, even without [fetch="join"], Hibernate kept generating the extra SELECT's. However, upon reading your suggestion, I got curious to see what would happen if I also removed [not-found="ignore"]:

Code:
<many-to-one column="maker_id" name="maker"/>


This change produced the results I wanted - no extra SELECT's, problem solved :) Thanks for pointing me in the right direction & best regards,

Roger


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