-
1. Re: Lazy loading design - surely I can't be right?
binario Mar 14, 2006 3:18 PM (in response to binario)anyone got any ideas?
-
2. Re: Lazy loading design - surely I can't be right?
nickthegreat Mar 20, 2006 6:47 PM (in response to binario)
was under the impression that as soon as I entered a method in a stateless session bean, under the hood the hibernate session is re-opened and therefore I can access any level in the graph that I want.
you are under the right impression.
in the stateless/stateful session bean you CAN access any level in the object graph ... of course you cant in any "higher" level
for me this always worked ok ... so it must be something stupid ...
plz try this:
public List getOrdersForUser(String userName)
{
User u = entityManager.find(User.class,userName);
// a check if a user with this name is actualy found wouldn't hurt
List orders = u.getOrders();
u.size(); // dummy operaton to initialize (fill) lazy collection
return L;
}
or a completely different query:
(not sure if really correct, but something like that)
...
em.createQuery("select o from orders o where o.user.name=:name");
em.setParamter("name", userName);
return em.getResultList();
hth, ntg -
3. Re: Lazy loading design - surely I can't be right?
nickthegreat Mar 20, 2006 6:48 PM (in response to binario)correction:
u.size(); // dummy operaton to initialize (fill) lazy collection
replace with ->
orders.size(); -
4. Re: Lazy loading design - surely I can't be right?
binario Mar 21, 2006 5:58 AM (in response to binario)Hi NickTheGreat,
First off, you are great to reply. Thanks so much. I was loosing faith :-).
Anyway, yes, I too have seen that calling the dummy method list.size() to initialize the collection works, however, my question is - why is this needed at all????
Anyway, if that is the fix everyone is using fair enough, but I have to say I think it's pretty awful. Surely when you do a call to --> u.getOrders(), eg:
{code}
public List getOrdersForUser(String userName)
{
User u = entityManager.find(User.class,userName);
// a check if a user with this name is actualy found wouldn't hurt
return = u.getOrders();
}
{code}
you would expect the collection to be accessed.
Anyway, I think this will lead to loads of problems, but thanks very much indeed for your help.
cheers,
Binario -
5. Re: Lazy loading design - surely I can't be right?
nickthegreat Mar 21, 2006 6:13 AM (in response to binario)
yes, I also find this rather unintuitive.
a lazy collection "per se" is a just an "empty" proxy object, that's only "filled with live" when actually being accessed.
returning a "pointer" of the proxy doesnt count as being accessed.
why it is designed that way -> you have to ask the hibernate creators :)
probably performance ... -
6. Re: Lazy loading design - surely I can't be right?
nickthegreat Mar 21, 2006 6:29 AM (in response to binario)Addition:
Yes, there is a "cleaner" workaround than e.g .size() on lazy collections before returning them if I remeber correctly.
But it's Hibernate specific ... something like Hibernate.initialize(lazyset) (too lazy to look up in hibernate reference, but it should be similar)
If you are using EJB3 because it's a standard rather than a particular implementation, Hibernate specific code aint good I guess.
Dont know if there's a real "clean" plain EJB3 solution, both avoiding dummy access to lazy collection before returing it or using hibernate specific code.
Personaly I prefer the .size() one, just get sure that it's good documented. -
7. Re: Lazy loading design - surely I can't be right?
binario Mar 21, 2006 9:23 AM (in response to binario)Of all the options, I agree with you, the .size() is definately the best - but I will restate my opinion in the hope that someone on the hibernate/ejb3 team reads it. I think this is a TERRIBLE design flaw.
Also, if the jboss ejb3 release goes like this then surely it should be documented CLEARLY. Please can this be an example on the docs.jboss.com/ejb3 tutorial pages. -
8. Re: Lazy loading design - surely I can't be right?
elkner Mar 21, 2006 11:48 AM (in response to binario)"binario" wrote:
I think this is a TERRIBLE design flaw.
Hmm, IMHO this is better, than blowing up the required code and introduce a more or less big performance problem and other trouble.it should be documented CLEARLY.
Yepp. +100 -
9. Re: Lazy loading design - surely I can't be right?
mazz Mar 21, 2006 12:00 PM (in response to binario)I'm not sure its a "terrible" design flaw. I think your wording might be overstating the issue. Is it unintuitive? Probably.
A previous post said it right - just getting the reference does not imply you are reading/accessing the data. It's conceivable you are just going to pass that refererence around and not yet access any of the data in the collection.
If you want to force the collection to be loaded, use EAGER fetching or don't use the find method; instead, perform a query that loads the collection with an inner join. -
10. Re: Lazy loading design - surely I can't be right?
binario Mar 21, 2006 12:53 PM (in response to binario)Hi guys,
thanks for the responses. I've looked some more at this and I see that this is what hibernate does under the hood by using, as Nick said, the "Hibernate.initialize(Object proxy) method.
I agree that "terrible" is probably overstated :-), but I definately think it is unintuitive and probably at least ... poor. For example, why would you ever want to callCollection orders = user.getOrders
and not use orders for something.
It's conceivable you are just going to pass that refererence around and not yet access any of the data in the collection.
That's where I think I disagree with you. I can't think of any situation where this might be the case. Surely, if you call get on something, you expect to get it back initialized if we're in the session.
At any rate, I don't mind at all, and I very much appreciate the help and I would just reiterate, clear documentation will help others avoid this non-obvious problem.
thanks again,
binario