-->
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.  [ 22 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: lazy fetching an association mapped as non-lazy
PostPosted: Thu May 22, 2008 11:51 am 
Newbie

Joined: Wed Sep 06, 2006 6:08 am
Posts: 11
Location: Rome, Italy
I have an entity (parent) with a series of child associations mapped as sets. Each of these associations is NOT mapped as lazy (ie. as proxy or eager - I have a mapping file with default-lazy="false")
So my default load behaviour pulls up the parent object with all of its child associations eagerly fetched, which is how I want it.
Now if I want to perform a single select which pulls up only the parent object, without querying the associated records, is there a way of doing it? I've tried the example in the reference manual for tuning with a criteria query and FetchMode.SELECT or LAZY (deprecated), but they don't seem to have any effect. I've also tried the criteria select without referring to the child queries at all but its the same.

This is the type of query I've tried:
Code:
User user = (User) session.createCriteria(User.class)
.setFetchMode("permissions", FetchMode.SELECT)
.add( Restrictions.idEq(userId) )
.uniqueResult();


Is there another way to achieve this, without changing the mapping file?


Top
 Profile  
 
 Post subject: Re: lazy fetching an association mapped as non-lazy
PostPosted: Thu May 22, 2008 2:28 pm 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
This is the default behaviour with HQL queries; they do not fetch associations unless specified.



Farzad=


Top
 Profile  
 
 Post subject:
PostPosted: Fri May 23, 2008 3:05 am 
Newbie

Joined: Wed Sep 06, 2006 6:08 am
Posts: 11
Location: Rome, Italy
OK, but is there a way to force Hibernate NOT to load the associations, without changing the mapping file. In my case I have dozens of queries in which I do want the eager fetching of the associations, but only one case in which I don't want it - for this exception case I was hoping to use a criteria or HQL setting to NOT fetch the associated entities.


Top
 Profile  
 
 Post subject:
PostPosted: Fri May 23, 2008 7:08 am 
Pro
Pro

Joined: Tue Jun 12, 2007 4:13 am
Posts: 209
Location: Berlin, Germany
kenstershiro wrote:
OK, but is there a way to force Hibernate NOT to load the associations, without changing the mapping file. In my case I have dozens of queries in which I do want the eager fetching of the associations, but only one case in which I don't want it - for this exception case I was hoping to use a criteria or HQL setting to NOT fetch the associated entities.

I have the same problem and found no way until now how to do this. I've searched in the book "JPA with Hibernate", but only found a confusing sentence which I could not verify in my app. At page 651 Bauer/King say:
Quote:
"HQL and JPA QL ignore any fetching strategy you've defined in metadata. (...) A dynamic fetching strategie igores the global fetching strategy (on the other hand, the global fetch plan isn't ignored."


I found this not to be true: all eager associations fetchings defined in the mappings are done if you do a query. And that was not what I wanted. But maybe I do not understand these statements. Indeed, the second cited sentence above confuses me: What is the difference between "global fetching strategy" and "global fetch plan"? Can anyone explain?

So, I did not use JPA /HQL but instead resorted to native SQL (what I wouldn't prefer).

Anyone with better ideas? (Yes, make all LAZY; but this would have other unwanted implications!)

Carlo


Top
 Profile  
 
 Post subject:
PostPosted: Fri May 23, 2008 7:09 am 
Pro
Pro

Joined: Tue Jun 12, 2007 4:13 am
Posts: 209
Location: Berlin, Germany
kenstershiro wrote:
OK, but is there a way to force Hibernate NOT to load the associations, without changing the mapping file. In my case I have dozens of queries in which I do want the eager fetching of the associations, but only one case in which I don't want it - for this exception case I was hoping to use a criteria or HQL setting to NOT fetch the associated entities.

I have the same problem and found no way until now how to do this. I've searched in the book "JPA with Hibernate", but only found a confusing sentence which I could not verify in my app. At page 651 Bauer/King say:
Quote:
"HQL and JPA QL ignore any fetching strategy you've defined in metadata. (...) A dynamic fetching strategie igores the global fetching strategy (on the other hand, the global fetch plan isn't ignored."


I found this not to be true: all eager associations fetchings defined in the mappings are done if you do a query. And that was not what I wanted. But maybe I do not understand these statements. Indeed, the second cited sentence above confuses me: What is the difference between "global fetching strategy" and "global fetch plan"? Can anyone explain?

So, I did not use JPA /HQL but instead resorted to native SQL (what I wouldn't prefer).

Anyone with better ideas? (Yes, make all LAZY; but this would have other unwanted implications!)

Carlo


Top
 Profile  
 
 Post subject:
PostPosted: Fri May 23, 2008 8:37 am 
Pro
Pro

Joined: Tue Jun 12, 2007 4:13 am
Posts: 209
Location: Berlin, Germany
You might want look at the question around these themes on the Hibernate Book forum:
http://forum.hibernate.org/viewtopic.php?t=987115

Carlo


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 01, 2008 11:33 am 
Beginner
Beginner

Joined: Tue Nov 06, 2007 5:13 am
Posts: 28
kenstershiro wrote:
OK, but is there a way to force Hibernate NOT to load the associations, without changing the mapping file. In my case I have dozens of queries in which I do want the eager fetching of the associations, but only one case in which I don't want it - for this exception case I was hoping to use a criteria or HQL setting to NOT fetch the associated entities.


I am also interessted in such a feature.
disable the default eager fetching strategy for criteria API to make it work exactly like HQL

does anyone have a solution for this yet?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 31, 2009 7:04 am 
Newbie

Joined: Tue Mar 31, 2009 6:48 am
Posts: 5
Dynamic fetching with criteria works only in one direction. When i have LAZY in mappings, and I'm trying to change it dynamically to EAGER - it works. But not the other way.

For me it is a bug...

The same with 3.2.6 and 3.3.1.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 02, 2009 5:37 am 
Newbie

Joined: Tue Mar 31, 2009 6:48 am
Posts: 5
If someone is interested i have found the solution.

One has to define new class implementing Projection, by extending IdentifierProjection. Then just one method has to be overriden.

public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
return new Type[] { new ManyToOneType(YourClass.class.getName()) };
}


It looks like criteria mechanism is still far from ideal. That's a pity, as, in times of object programming, object oriented query generation is something that i really like. The above solution makes listing query as short as query generated with count projection - so no tables are being joined except for those needed as filtering parameters.


Top
 Profile  
 
 Post subject: .Net
PostPosted: Tue Apr 07, 2009 5:24 am 
Beginner
Beginner

Joined: Fri Sep 26, 2008 9:19 am
Posts: 20
Location: Belgium
pabloii wrote:
If someone is interested i have found the solution.

One has to define new class implementing Projection, by extending IdentifierProjection. Then just one method has to be overriden.

public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
return new Type[] { new ManyToOneType(YourClass.class.getName()) };
}


It looks like criteria mechanism is still far from ideal. That's a pity, as, in times of object programming, object oriented query generation is something that i really like. The above solution makes listing query as short as query generated with count projection - so no tables are being joined except for those needed as filtering parameters.



Hey guys, I'm also having the same issue.. i'm having really nice objects with lots of collections in it, but when loading a list this is of course not that great. i'm getting quite allot of information that I don't need, and i would like to keep working with Criteria because i'm not support HQL in my methods.
I've built some easy methods where in you can add a list of criteria to get data out of a WCF Service (.Net of course)

By the hand of your explenation of implementing Projection and extending IdentifierProject I actually still don't know what to do..
Can you give a small example please?

Thanks allot


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 07, 2009 8:32 am 
Beginner
Beginner

Joined: Fri Sep 26, 2008 9:19 am
Posts: 20
Location: Belgium
The solution to all your problems::

create a mapping with lazy set to true. you can now always get a list of objects that do not contain the relational mappings

when you do need the relational stuff, you just have to do this:

criteria.Add("<PropertyName>",FetchMode.Join);


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 07, 2009 9:33 am 
Beginner
Beginner

Joined: Tue Nov 06, 2007 5:13 am
Posts: 28
santo2 wrote:
The solution to all your problems::

create a mapping with lazy set to true....

no - that's not the solutioin - its an akward workaround:
when you have a case where you need eager fetching in 99% of the cases, it makes perfect sense to define the relation as eager and to deactivate this default for just the one % of cases where you don't need or want it.

hibernate should support his OOTB.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 07, 2009 9:38 am 
Beginner
Beginner

Joined: Fri Sep 26, 2008 9:19 am
Posts: 20
Location: Belgium
you only have to set the lazy = true to one mapping you use with the relational objects.
I don't know how you built your datalayer, but in my case i just had to replace a small part of my code to make it work in any case, for any object in the whole database. (Added an attribute to the collections that had to have the possibility to be set to lazy. in the case the attribute is there, in the get methods my property will be lazy false, in the load list methods my property will be lazy true.

It's how good you are in implementing it :)


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 07, 2009 11:16 am 
Beginner
Beginner

Joined: Tue Nov 06, 2007 5:13 am
Posts: 28
maybe we are talking about different issues - I'll try to give a simple example.

let's say we have a web-application which has Users and the User entity has an association to an Image Entity.
In all the webpages, I want to display the Image (if the User has one): so I'll set eager fetching on the association.

Now that's fine - whenever you use a criteria and join to the User Entities the Image entities will automatically be eager fetched - great! Developers don't have to write any code for this join and thus can't forget about it.

But now I have one administration page, where the admin should be presented with a simple list of a subset of User-names and adresses for the purpose to send a plain old mail to their postal adress. In this very special case I don't need/want eager fetching of Images. So it would be nice, if I could just turn it off for this one criteria.

Of course there are alternatives:
  • use HQL: it'll ignore the global eager fetching anyway
  • set the global eager fetching to false: then you had to change all existing criterias that had implicitly joined to the Images before: involves very error prone refactoring.
  • and maybe the getTypes() stuff that I haven't tested (yet)
[/list][i][/code]


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 08, 2009 5:29 am 
Beginner
Beginner

Joined: Fri Sep 26, 2008 9:19 am
Posts: 20
Location: Belgium
yes i know the feeling.
I was also first looking for it like you are still doing, but it doesnt seem to be available right now to do it like that.
If you find it, of course i would be really greatfull if you would share it here in the future.

My way of doing it is a workaround but for now it's the best one i know.
it's not that you have to change thousands of rules of code to make it work like you would like it to work.

If it's really an exception of using the object without it's relation, maybe you could best do it with HQL?

Or if you get more information on the GetTypes thing i hope you also share it over here.

Greets


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 22 posts ]  Go to page 1, 2  Next

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.