-->
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.  [ 8 posts ] 
Author Message
 Post subject: LazyInitializationException and session?
PostPosted: Tue Jun 03, 2008 3:42 pm 
Newbie

Joined: Fri May 30, 2008 9:05 am
Posts: 18
Hello, Sorry for my bad english!

I have read the article (not in details, I have quickly searched for specific things) proposed to explain the use of sessions in hibernate, but some things are not clear for me.

In fact, when I try to get a collection from my entity, I have the following error:
Code:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: app.ejb.entity.Person.addresses, no session or session was closed


Sorry if this question is stupid, but I don't use a transactional method here, so where does this notion of session comes from in this case?
It would have been clear for me if I was trying to do something like:

Code:
session bean:
public void doTransaction(){
      entity1.operation();
      entity2.operation();
      ....
}


But I just do, in a jsp:
Code:
entity.getAddresses();


So I don't understand.

Does someone can explain me the problem, when use session, and how use them (very quickly sure)? Or simply give me the solution, I suppose I will understand too :)

I hope I am clear,
Thanks in advance.


Top
 Profile  
 
 Post subject: Re: LazyInitializationException and session?
PostPosted: Tue Jun 03, 2008 3:56 pm 
Newbie

Joined: Tue Jun 03, 2008 3:49 pm
Posts: 6
Location: Dominican Republic
Hi,

org.hibernate.LazyInitializationException is the most common exception when trying to deal with association and your "Hibernate Session" is close.

Please check the Open Session In View Pattern:
http://www.hibernate.org/43.html

rageice wrote:
Hello, Sorry for my bad english!

I have read the article (not in details, I have quickly searched for specific things) proposed to explain the use of sessions in hibernate, but some things are not clear for me.

In fact, when I try to get a collection from my entity, I have the following error:
Code:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: app.ejb.entity.Person.addresses, no session or session was closed


Sorry if this question is stupid, but I don't use a transactional method here, so where does this notion of session comes from in this case?
It would have been clear for me if I was trying to do something like:

Code:
session bean:
public void doTransaction(){
      entity1.operation();
      entity2.operation();
      ....
}


But I just do, in a jsp:
Code:
entity.getAddresses();


So I don't understand.

Does someone can explain me the problem, when use session, and how use them (very quickly sure)? Or simply give me the solution, I suppose I will understand too :)

I hope I am clear,
Thanks in advance.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 03, 2008 5:07 pm 
Newbie

Joined: Fri May 30, 2008 9:05 am
Posts: 18
Thank you for the answer.

Ok, there are some things I understand and some others I don't. I think I am a little bit hampered by the language (or it is my excuse for not say I am stupid :-) ).

In particular, the main thing I don't understand is:
What is the difference between a call to getAddress in the business tier and in the view tier? (Yes, this question shows I have nothing understood :-) , but in fact I don't understand the most important). Is this in relation with JNDI, the internal functionment of the persistent unit, or what else? Because personnally, I see the manager I use in my servlets (annotated @EJB) as a simple link towards the manager really loaded in the business tier.

And again a little question:
Isn't it a solution to map the entity to another bean in the view tier?


Thanks again for answers.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 03, 2008 6:19 pm 
Newbie

Joined: Tue Jun 03, 2008 3:49 pm
Posts: 6
Location: Dominican Republic
rageice,

When you load a class via Hibernate Session, what u obtain is Proxy Class (Research about Java Dynamic Proxy), that will fetch any association on demand. e.g : When you call "myPojo.getAddress().size()"

At that precise moment, hibernate will launch the corresponding SQL statement to fill the collection for you, but in order for that to happen the Hibernate Session must be OPEN

There, you must relay on the Open Session in View Pattern, to keep the session Open while your View (JSP) is being rendered by the container.

If you want to get a dirty work around on this you, so you can understand better about the importance of the Session you can do the following:


On top of your JSP you can call:

Code:
HibernateUtil.getSessionFactory().getCurrentSession();


And in the bottom just call:
Code:
HibernateUtil.getSessionFactory().getCurrentSession().close();


Remember, that's just a quick and dirt work around so you can understand
why the session must be open if you try to access any Lazy Association
from your View (JSP).

The above code assume you have at least the common HibernateUtil to get access to you SessionFactory.

rageice wrote:
Thank you for the answer.

Ok, there are some things I understand and some others I don't. I think I am a little bit hampered by the language (or it is my excuse for not say I am stupid :-) ).

In particular, the main thing I don't understand is:
What is the difference between a call to getAddress in the business tier and in the view tier? (Yes, this question shows I have nothing understood :-) , but in fact I don't understand the most important). Is this in relation with JNDI, the internal functionment of the persistent unit, or what else? Because personnally, I see the manager I use in my servlets (annotated @EJB) as a simple link towards the manager really loaded in the business tier.

And again a little question:
Isn't it a solution to map the entity to another bean in the view tier?


Thanks again for answers.
[/quote]


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 03, 2008 11:42 pm 
Senior
Senior

Joined: Mon Feb 25, 2008 1:48 am
Posts: 191
Location: India
When you say a collection or association is lazy, you mean that you want hibernate to fetch the collection/association only when you request for it. So the moment you call entity.getAddresses(), hibernate will try to fetch the collection/association by firing an SQL query. But for this lazy SQL firing to happen, you should be within the scope of the session where you retrived "entity". If the session is closed before entity.getAddresses(), hibernate has no way to fetch the collection you lazily requested for. So before u make a call to entity.getAddresses(), just make sure the hibernate session is open. Hope that helps.

_________________
Sukirtha


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 04, 2008 5:31 am 
Newbie

Joined: Fri May 30, 2008 9:05 am
Posts: 18
Thank you for answers.
The english is probably very bad in this post :-)

Ok, in fact I think I have understood. And I will precise elements that I needed for this (it could maybe help someone). Firstly, we have to know that, when a stateless bean executes a method, it creates a transaction. This explains why there is no need to do any particular manipulation in the business tier (effectively, when we need data in the business tier, we generally use a session bean).
But sure, if I am in my VIEW tier, and that after I obtain a reference of my entity, if I have to call a method on this entity which implies a transaction, then I have to do the necessary manipulations (explain in the article in previous posts), because I don't use a method of the stateless that will do these manipulations for me.

But the solutions you give does not seem to be the betters for a portable code, am I wrong.
Wouldn't it be better to create a method in my stateless like: getAddressesFromPerson(Person person), and with this I don't need to use HibernateUtil
?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 09, 2008 9:59 am 
Expert
Expert

Joined: Tue May 13, 2008 3:42 pm
Posts: 919
Location: Toronto & Ajax Ontario www.hibernatemadeeasy.com
One of the major reasons people run into this LazyInitialization Exception is simply due to assumptions made about how hibernate works, and how objects in the session work.

When working with Hiberante, you need an open session to grab the properties of various objects that have been loaded into the Hiberante session. Even if you load an object, if you close the session, and try to access properties of that JavaBean for the first time, you'll be getting a proxy, not the real JavaBean, and as Hibernate tries to replace the proxy with the real information from the database, it will find that it doesn't have a valid session to use to connect to the database, and the LazyInitializationException happens.

Here's a little tutorial on How Hibernate Works that you might find helpful. It tends to really help people understand how Hibernate does what it does. It will also help you avoid various common problems encountered when working with Hibernate.

http://jpa.ezhibernate.com/Javacode/learn.jsp?tutorial=07howhibernateworks

_________________
Cameron McKenzie - Author of "Hibernate Made Easy" and "What is WebSphere?"
http://www.TheBookOnHibernate.com Check out my 'easy to follow' Hibernate & JPA Tutorials


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 09, 2008 10:45 am 
Newbie

Joined: Fri May 30, 2008 9:05 am
Posts: 18
Yes, thank you for your answer, I have now understood this.

My question is now a little bit different. I don't want to use a filter in my view (because I think this implies the use of hibernate classes, and I want a portable code for my application.

So I have tried a first solution consisting in map my entities to beans in the view tier. This can appear to be strange, but I will integrate JSF later, so it can maybe be an interesting solution.

And i have found an other solution too, consisting in use EJB-QL to force the load of lazy relations, when needed. Sure, the disadvantage is that when the list is loaded like this, it is definitive for the current user session, but finally, it is interesting too.

So I am actually on an new problem, and I would be happy to have any answer. I am actually trying to use EJB-QL for load the contacts of a person. This is a ManyToMany relation on the class person (A person has contacts, and these contacts are themselves Persons).

So this is the important part of my entity for this relation to be understood:

Code:
import java.io.Serializable;
import java.util.Collection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;


@Entity
@Table(name="PERSON")
@NamedQueries({....
    @NamedQuery(name="person.lazyLoadContacts",
                query="SELECT contacts FROM Person contacts JOIN contacts.persons AS p WHERE p.id LIKE :id")
})
public class Person implements Serializable {
    ....
    ....
    /* ManyToMany relation attributes */
    private Collection<Person> contacts;
    private Collection<Person> persons;
   
    public Person(){  }
   
   
    public Person(String name){
        this.name= name;
    }
   
    /********************************/
   
    @ManyToMany
    @JoinTable(
        name="PERSON_CONTACT",
        joinColumns=@JoinColumn(name="ID_PERSON", referencedColumnName="ID"),
        inverseJoinColumns=@JoinColumn(name="ID_CONTACT", referencedColumnName="ID")
    )
    public Collection<Person> getContacts(){
        return this.contacts;
    }
   
    public void setContacts(Collection contacts){
        this.contacts= contacts;
    }
   
    @ManyToMany(mappedBy="contacts")
    public Collection<Person> getPersons(){
        return this.persons;
    }
   
    public void setPersons(Collection<Person> persons){
        this.persons= persons;
    }
}



I know my EJB QL is wrong but I don't know why (I have an idea, but I don't find the solution). So, do you see how to correct this?

I would also be happy to have your opinion about my ideas about the management of the lazy relations.

One more time, thanks for your answers. I really helps.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 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.