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.
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...
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).
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.
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) ?
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.
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 ]
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??
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.