This week's book giveaway is in the Agile and Other Processes forum.
We're giving away four copies of The Little Book of Impediments (e-book only) and have Tom Perry on-line!
See this thread for details.
Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

failed to lazily initialize a collection - no session or session was closed

 
Mark Kafe
Ranch Hand
Posts: 60
Hibernate Java Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi To All
i face this errors


when i close session after findById methods then this errors occur.......if i not close session then it working fine



failed to lazily initialize a collection - no session or session was closed.

please tell me why this error occur...........

if i not Close session then any problems in my application?
 
Sean Clark
Rancher
Posts: 377
Android Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey,

Are you using hibernate? This sounds like you are trying to access the attributes of your loaded object after you have closed the session.
By default hibernate does not load data from joined tables but creates a proxy to them and loads them from the database when they are accessed.

Can we see the code where you are making your database call?

Sean
 
Cameron Wallace McKenzie
author and cow tipper
Saloon Keeper
Posts: 4968
1
Hibernate Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, I think you're discovering the value of the "Open Session in View" design pattern expoused by the gurus at Hibernate. If you keep that Session open, even right through the View Generation phase, you won't have any Lazy exceptions, AND, you'll minimize the number of transactions that get opened and closed.

There are a variety of issues that might be going on here, but basically, you are not getting all the information when you load an object. Hibernate tries not to put too much of a burden on the DB, so it only loads a slim amount of data. However, if you neeed more than is loaded, you might get in trouble.

There are alot of ways around this. Maybe just changing from loads to get calls on the Hibernate Session might solve your problem. Here's a little section from my book "Hibernate Made Easy" about the difference between load and get. (Actually, I pulled it from my website.)

Well, if you were to compare the load and get methods of the Hibernate Session, you'd think that they looked pretty darned similar; and you'd be correct, but there are subtle and very important differences.

First of all, the get method hits the database as soon as it is called. So, using the Hibernate Session's get method will always trigger a database hit. On the other hand, the load method only hits the database when a particular field of the entity is accessed. So, if we use the load method to retrieve an entity, but we never actually access any of the fields of that entity, we never actually hit the database. Pretty kewl, eh?

Well, actually, as kewl as the load method might sound, it actually triggers more problems than it solves, and here's why. If you initialize a JavaBean instance with a load method call, you can only access the properties of that JavaBean, for the first time, within the transactional context in which it was initialized. If you try to access the various properties of the JavaBean after the transaction that loaded it has been committed, you'll get an exception, a LazyInitializationException, as Hibernate no longer has a valid transactional context to use to hit the database.

So, while this code will work just fine?..

session.beginTransaction();
User user=(User)session.load(User.class, new Long(1));
System.out.println(user.getPassword());
session.getTransaction().commit();
.. this code will fail ?..

session.beginTransaction();
User user=(User)session.load(User.class, new Long(1));
session.getTransaction().commit();
System.out.println(user.getPassword());
.. and generate the following error, telling you that since the transaction was committed, there was no valid Session in which a read transaction against the database could be issued:

org.hibernate.LazyInitializationException:
could not initialize proxy - no Session
So, the big thing to take away from this is that with the load method, you can't really use your loaded JavaBeans after the transaction has been committed, whereas, with the get method you can, because all of the various properties of a JavaBean retrieved through the get method are initialized right away.


How Hibernate Works

Regards,

-Cameron McKenzie

 
Mark Kafe
Ranch Hand
Posts: 60
Hibernate Java Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here the code
try {


instance = new AppUser();
instance = (AppUser) getSession().get(
"com.itcentrix.altcp.Security.AppUser", id);
AppUser appUser = new AppUser();
instance = appUser.lazyInitialize(instance);

} catch (RuntimeException re) {
log.error("get failed", re);
throw re;
}
finally
{
getSession().flush();
// getSession().close();
// HibernateSessionFactory.closeSession();
}
return instance;



if i close session in finally block then this errors occur if i not close session then it working fine................
 
Cameron Wallace McKenzie
author and cow tipper
Saloon Keeper
Posts: 4968
1
Hibernate Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The solution would be to keep the session open, and close it later on in the lifecycle of the application. Check out the "Open Session in View" design pattern for more info. I think that's what's working for you.

You need to close it eventually! I'm not sure if you need the flush though.

-Cameron McKenzie
 
Mark Kafe
Ranch Hand
Posts: 60
Hibernate Java Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hmm...ok

But if i not close session.........then it have any Disadvantage for sessions remaining open???
 
Eduardo Bueno
Ranch Hand
Posts: 155
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can get in trouble with a certain chain of commands, since hibernate's session works as a first level cache.
 
Cameron Wallace McKenzie
author and cow tipper
Saloon Keeper
Posts: 4968
1
Hibernate Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
then it have any Disadvantage for sessions remaining open


Well, you need to close it eventually. But active closing of the session is a waste. You want to open it when needed, and close it when you're finished. That's obviously not happening now, because you get lazy initialization problems. Another option might be to open a new session, but that would be a horribly inefficient solution, because it would kick off a new transaction, and cause more read and writes to the database.

Keep the session open, and close it when you're done with it!

-Cameron McKenzie

 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic