-->
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: Many to One Collection Syntax Question
PostPosted: Sat Sep 03, 2005 5:40 pm 
Beginner
Beginner

Joined: Wed Apr 13, 2005 2:03 pm
Posts: 34
Hibernate version:
3.0.3

Mapping documents:

<joined-subclass name="core.User" table="user">
<key>
<column name="user_id" length="32"></column>
</key>
<property name="login" column="login" type="string"/>
<property name="password" column="password" type="string"/>
<property name="editBar" column="editbar" type="integer"/>
<property name="listLinks" column="listlinks" type="integer"/>
<property name="dateFormatString" column="dateformat" type="string" />
<many-to-one outer-join="true" name="currentRole" class="security.Role" fetch="join" >
<column name="crole_id" length="32"></column>
</many-to-one>
</joined-subclass>

Code between sessionFactory.openSession() and session.close():
String sql = "from User";
Session s = HibHelper.getSession();
Query q = HibHelper.getSession().createQuery(sql.toString());
q.setCacheable(false);
List l = q.list();

The problem:

I've got like 1000 users in the system. If I want a list of 1000 of them, I don't really want to load their current roles. Most of hte time I will never, ever, reference the currentRole field.

However, when I run the question above and the SQL logs on, I see one query for the users, and then 1,000 discrete queries as each and every user loads its current role.

Ideally, I'd like to delay loading the currentRole at all unless and until it gets referenced. I *thought* that by declaring the collection with lazy="true" that's what I'd get, but no dice.

So I took the alternate appraoch and decided to just outer-join fetch it all, or so I thought, but even with the outer join tag in place in the xml, I'm still seeing discrete element queries instead of currentRole being included in the initial List query.

So, could somebody please offer a suggestion on how to either:

A) Get Lazy loading to work here.
B) At least get an outer-join fetch to work.

Any assistance would, as usual, be appreciated.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 05, 2005 7:06 am 
Regular
Regular

Joined: Tue Oct 07, 2003 10:20 am
Posts: 77
Have you read the section on fetching strategies in the Hibernate docs (http://www.hibernate.org/hib_docs/v3/reference/en/html_single/#performance-fetching-custom)? This may help for your problem.

I believe that HQL queries do not use the lazy or fetch settings in the mapping files, so if you wish to bring back the role you'll need a query that looks something like the following:
Code:
from User user left join fetch user.currentRole


Your class may not be being lazily loaded if the class is final or any of its methods are final. Also, you may want to manually specify the proxy class for the Role class, in the Role mapping file - you can just set this to the class itself, although Hibernate should be doing this automatically. Also ensure you haven't turned off CGLIB proxies, via the hibernate property file.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 05, 2005 8:27 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
sdknott wrote:
Also ensure you haven't turned off CGLIB proxies, via the hibernate property file.

Just a remark.
CGLIB proxies for lazy loading cannot be turned off.
Reflection optimization through CGLIB can.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 05, 2005 9:09 am 
Regular
Regular

Joined: Tue Oct 07, 2003 10:20 am
Posts: 77
Cheers for the clarification!


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 05, 2005 9:19 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Quote:
CGLIB proxies for lazy loading cannot be turned off.


Actually they can be turned off in 3.1 by setting lazy="false" in all <class> mappings and using lazy="no-proxy" on many-to-one/one-to-one, with bytecode instrumentation, for fetching optimization.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 05, 2005 12:17 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
christian wrote:
Quote:
CGLIB proxies for lazy loading cannot be turned off.


Actually they can be turned off in 3.1 by setting lazy="false" in all <class> mappings and using lazy="no-proxy" on many-to-one/one-to-one, with bytecode instrumentation, for fetching optimization.


Well, not really turned off. The proxy is still there and generated, but it is not visible from the application code.

_________________
Emmanuel


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.