• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Same old song, same old dance, Lazy Hibernate

 
Hussein Baghdadi
clojure forum advocate
Bartender
Posts: 3479
Clojure Mac Objective C
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi.
Well, this post is about our dear exception, Lazy exception.

OrderAction is a Struts action :

User, Order and OrderItem are my POJOs.
Well, I got a LazyInitializtionException at this.getOrders().add(order); line.
Actually, I have beed reading Hibernate In Action ch4 when the authors created the laptops category and added it to the detached computer category object.
How to solve this problem ?
Gracias.
 
Francois-Xavier Douxchamps
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The problem is that the collection is not loaded automaticaly.
With hibernate 3, only the minimum is loaded. Then when we return a object not completely loaded outside the hibernate session, this exception occurs.

The solution is to mark the collection lazy=false in the hibernate mapping. With this, hibernate will automaticaly load this collection. And this exception will disappear...
 
Hussein Baghdadi
clojure forum advocate
Bartender
Posts: 3479
Clojure Mac Objective C
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
All my mappings are lazy ...
But the problem (as I see it), there is no opened-session when addOrder( ) is called and even if I have all my mappings are lazy, an exception will be thrown.
 
Paul Sturrock
Bartender
Posts: 10336
Eclipse IDE Hibernate Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You are half there. If your associated objects are mapped to use lazy initialization they will only be populated when they are requested. And they can only be populated if there is an open session to use. Lazy initialization will not open a new session if one does not exist.

Francois-Xavier Douxchamp's solution is only a solution if you are happy to eagerly fetch all your associated object up front. This tends not to be the norm, since it will brings back far more than you really need (i.e. a record plus all related data).
 
Halcon Guatemala
Ranch Hand
Posts: 57
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi to @ll, I'm confused about use of "lazy" option when the option is used in 2 levels, to say between father, son and niece classes. I know it was explained in HiA and I hope it will be again in "Java Persistence with Hibernate", but I'd regard You deep about this theme.

Thanks in advance
 
Hussein Baghdadi
clojure forum advocate
Bartender
Posts: 3479
Clojure Mac Objective C
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Paul,
Did you read ch4 of 'Hibernate In Action' ?
How did the authors create a transient laptops objects and add it to the detached computer object ?
In my application, I followed the same methods and the same logic ?
What if I called session.update(orderer) instead of session.save(order) ?
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think the key thing to think of here is this.

You have a Session which has a connection to the database. Outside of this context, you cannot connect to the database.

So if the object you currently hold are not initialized, then how will you connect to the database outside of the Session? You can't.

Now in the laptop example, you can still add and set stuff into the objects you currently hold, you are just working with a Java object, just like any other.

When you open a new session and call save or update, that "detached" Java Object is now being managed by the Session and will have access to a database connection to do its work. when you flush or commit.

Mark
 
Hussein Baghdadi
clojure forum advocate
Bartender
Posts: 3479
Clojure Mac Objective C
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Mark,
I understand all what you have said, but ...
I don't know how to solve the problem.
My code manipulate some object graph outside any transaction (as HIA mentioned) in the presintation layer, then I pass it to persistence manager to propagate the changes to the database.
And if it is ok to manipulate objects outside a transaction (orderer.addOrder(order) in my case) , why I got this exception ?
May I ask you to check pages # 135 and 136 of HIA please ?
I followed the text literaly.
[ December 12, 2006: Message edited by: John Todd ]
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Maybe it is the User object that is just a proxy object and not initialized. so the getOrders() is the problem, try breaking up that line into two lines to wee which part returns the exception.

How do you get the user object? if you use session.load(User.class, userID) then that returns a proxy object, try using session.get(User.class, userID) instead.

Mark
 
Hussein Baghdadi
clojure forum advocate
Bartender
Posts: 3479
Clojure Mac Objective C
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, I don't want to hijack the thread but actually I'm using Spring.

I can't use session.get( ) or session.load( ) since I'm using surrogate keys, so I'm forced to use HQL.
Do you suggest to include orders field in the HQL (since it mapped as lazy) ?
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Probably. I suggest adding a FETCH JOIN to the externalized named query for eager fetch the orders.

Good Luck.

Mark
 
Mr. C Lamont Gilbert
Ranch Hand
Posts: 1170
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I had similar problem in JDO. If you never load the field, then you could not access it even outside of a transaction.

Lazy loading only functioins within a session. It can not function outside of a session. So if you plan on working with it outside of the session, then you need to ensure that it was loaded by a session at some point.

If I may ask an additional question of Hibernate folks? How does not force a collection to full load if that collection was defined as lazy in the xml? Can I say session.load(object.field) where field is the collection field??
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
How does not force a collection to full load if that collection was defined as lazy in the xml? Can I say session.load(object.field) where field is the collection field??


No, while in the session, just access the attribute, and Hibernate will load it for you. Actually in Lazy mode, there is still a COllection with Object, but those objects are proxies. so they have code in there that will see that you just accessed it and go to the datbase to load that data. The Proxies will just have their ID filled in.

Mark
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic