目前使用较旧的Hibernate(3.3.2.GA) - 并在事务边界内获取org.hibernate.LazyInitializationException。我确认调用方法标记为@Transactional
,并且异常时的堆栈跟踪也显示出来:
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
但是,尝试迭代@CollectionOfElements
会立即抛出LazyInitializationException,“没有会话或会话被关闭”。
在调试它时,我看到相关集合上的Hibernate代理几乎在Hibernate加载时就会有一个null会话。这有点担心吗?如何跟踪并解决此问题 - 换句话说,在调试时,跟踪会话发生情况的最佳方法是什么?
显然我明白将集合更改为Eager抓取将解决问题,但我想弄清楚为什么Lazy Load无法正常工作,因为在大多数情况下不需要这个(可能的)大型集合。
谢谢!
答案 0 :(得分:0)
我的猜测是,当你从获取实体的方法返回并开始迭代它时,你已经处于不同的事务上下文中,从而导致了惰性初始化问题;如果您正在使用DAO,请尝试将这两种方法设置为同一事务(即将它们设置为REQUIRED)。
但是,我可能完全错了。我刚刚使用EJB3 + JPA对此进行了测试,并且在获取实体的方法处于不同的事务上下文时遇到了您所描述的延迟初始化问题。 编辑:就像baba在评论中所说的那样,更好的解决方案是通过HQL / Criteria(HQL中的fetch join子句)急切地获取,或者更不利的是,在返回它之前使用Hibernate.initialize。答案 1 :(得分:0)
adir1我有完全相同的问题。在我的情况下,问题是由于包含延迟加载的集合的实例之前已被手动驱逐(全部在事务边界内)。
答案 2 :(得分:0)
关于这个问题的年龄,后人:
同样的问题发生在我身上,因为我将实体缓存在内存中。在稍后的事务中访问这些实体时会抛出异常 - 与首次收集实体的实体不同。因此失去了会话问题。
通过设置适当的第二级缓存来解决。