2011-03-17 72 views
3

错误为failed to lazily initialize a collection, no session or session was closed延迟获取会话错误

有很多人问几乎相同的问题,但分辨率并不那么直观。而且,我觉得有必要发布另一个问题来形容奇怪的错误信息:(我不打算在这里粘贴的源代码,因为它太长)

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 [[email protected]] for Hibernate transaction 
DEBUG [main] (HibernateTransactionManager.java:523) - Not preparing JDBC Connection of Hibernate Session [[email protected]] 
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.LazyInitializationException: 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 [[email protected]] 
DEBUG [main] (HibernateTransactionManager.java:734) - Closing Hibernate Session [[email protected]] after transaction 

正如你所看到的,当lazy-fetch被触发时,发生错误,已经有一个线程绑定的会话,并且在事务回滚之前它还没有关闭。

那么,它为什么报告有no session or session was closed

编辑 的相关来源:

@Transactional 
public void tcList() { 
    for (Cat cat : dao.list()) { 
     System.out.println("Saved cat: " + cat); 
    } 
} 
+0

你在JUnit测试用例中运行这个吗? – 2011-03-17 19:30:17

回答

2

线程有一个会话绑定到它,但是是否由本会话管理的catList?该会话可能已通过hibernate模板在dao.list()内部关闭,该模板负责处理样板代码。

排除问题的一种方法是在返回列表之前调用dao.list()函数内的list.get(0).someGetter()。这将填充实际值的列表,不应该导致延迟初始化异常。如果Cat由延迟初始化的其他对象组成,则应该为它们调用getter属性,以防您想要使用这些属性。

另外,尝试删除dao.list()方法上的任何Transactional注释(如果有的话)。使用由调用函数创建的事务,而不是使用Propagation_Required属性。如果你在dao.list()上使用了@Transactional,事务管理器可能会从这个函数返回时触发一个transaction.commit()/ session.close(),所以catList变成一个分离的实体,所有的猫都是仍然代理。

0

实体可能会从会话和懒加载收集被分离只是一个代理?如果你想使用它,你需要将它合并到一个会话中?

+0

合并是一项代价高昂的操作 – BDR 2014-01-30 16:26:46

0

这意味着您正在尝试加载/初始化会话中的集合。也许你必须保持会话活着,直到你完成你的操作.....意味着你必须使用一些胶水代码来管理你的会话资源...... ppl会建议初始化实体的set方法中的懒惰集合。使用惰性取指就像没有意义的一样,直到操作可能是最好的方式。保持活动状态。