Weired session error in lazy-fetch
The error is failed to lazily initialize a collection, no session or session was closed
.
There are many people asked nearly the same question, but the resolution are not so much intuitive. And, I think it's necessary to post another question to describe the strange error message:
(I'm not going to paste the source codes here because it's too long.)
DEBUG [main] (AbstractPlatformTransactionManager.java:365) - Creating new transaction with name [com.bee32.plover.orm.feaCat.FeaturePlayer.tcList]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' DEBUG [main] (HibernateTransactionManager.java:493) - Opened new Session [org.hibernate.impl.SessionImpl@19006c9] for Hibernate transaction DEBUG [main] (HibernateTransactionManager.java:523) - Not preparing JDBC Connection of Hibernate Session [org.hibernate.impl.SessionImpl@19006c9] DEBUG [main] (HibernateTemplate.java:397) - Found thread-bound Session for HibernateTemplate Hibernate: /* criteria query */ select ... ERROR [main] (LazyInitializationException.java:42) - failed to lazily initialize a collection, no session or session was closed org.hibernate.LazyInitializationEx开发者_JAVA技巧ception: failed to lazily initialize a collection, no session or session was closed at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380) ... at java.util.HashSet.<init>(HashSet.java:116) ... at org.hibernate.loader.Loader.list(Loader.java:2124) ... at org.springframework.orm.hibernate3.HibernateTemplate$5.doInHibernate(HibernateTemplate.java:590) ... DEBUG [main] (HibernateTemplate.java:422) - Not closing pre-bound Hibernate Session after HibernateTemplate DEBUG [main] (AbstractPlatformTransactionManager.java:843) - Initiating transaction rollback DEBUG [main] (HibernateTransactionManager.java:672) - Rolling back Hibernate transaction on Session [org.hibernate.impl.SessionImpl@19006c9] DEBUG [main] (HibernateTransactionManager.java:734) - Closing Hibernate Session [org.hibernate.impl.SessionImpl@19006c9] after transaction
As you see, when lazy-fetch is trigged, the error occurred, there already have a thread-bound session, and it's not yet closed until the transaction is rolled back.
So, why it reports there is no session or session was closed
?
EDIT The related source:
@Transactional
public void tcList() {
for (Cat cat : dao.list()) {
System.out.println("Saved cat: " + cat);
}
}
The thread has a session bound to it, but is the catList managed by this session or not? The session might have been closed inside the dao.list() by hibernate template which takes care of the boilerplate code.
One way to sort out the problem would be call list.get(0).someGetter() inside the dao.list() function before returning the list. This will fill up the list with the actual values and should not cause a lazy initialization exception. If the Cat is made up of further objects which are lazy initialized, you should call a getter property on them too in case you want to use those properties.
Also, try removing any Transactional annotation on the dao.list() method, if any. Use the transaction created by the calling function, rather than using the Propagation_Required attribute. If you have used @Transactional on dao.list() the transaction manager could be triggering a transaction.commit()/session.close() on returning from this function, so the catList becomes a detached entity, in which all the cats are still proxies.
The entity might be detached from the session and the lazy to load collection is just a proxy? If you want to use it, you need to merge it into a session?
This means you are trying to load/init the collection out of session. Probably u must be maintain session alive until u finish ur operation..... meaning u have to manager your session resource using some glue code... ppl would suggest to init the lazy collection in set method of an entity . it does not make sense to use lazy fetch like an eager fetch .keeping session alive till operation could be the best way....
精彩评论