Java 事务中的org.hibernate.LazyInitializationException异常

Java 事务中的org.hibernate.LazyInitializationException异常,java,hibernate,lazy-loading,Java,Hibernate,Lazy Loading,目前正在使用稍旧的Hibernate(3.3.2.GA)-并在事务边界内获取org.Hibernate.LazyInitializationException。我确认调用方法被标记为@Transactional,并且异常时的堆栈跟踪也显示了它: org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110) 尽管如此,尝试迭代@collection

目前正在使用稍旧的Hibernate(3.3.2.GA)-并在事务边界内获取org.Hibernate.LazyInitializationException。我确认调用方法被标记为
@Transactional
,并且异常时的堆栈跟踪也显示了它:
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)

尽管如此,尝试迭代
@collectionfements
会立即抛出LazyInitializationException,并显示“没有会话或会话已关闭”

在调试它时,我看到相关集合上的Hibernate代理在Hibernate加载时实际上有一个null会话。这有什么好担心的吗?我如何跟踪并解决这个问题?换句话说,在调试时,跟踪会话发生的情况的最佳方法是什么

显然,我理解将集合更改为急切抓取将解决这个问题,但我还是想知道为什么延迟加载不起作用,因为在大多数情况下不需要这个(潜在的)大型集合


谢谢大家!

我的猜测是,当您从获取实体的方法返回并开始遍历实体时,您已经处于不同的事务上下文中,因此导致了延迟初始化问题;如果您使用的是DAO,请尝试将这两种方法设置为同一事务(即根据需要设置它们)

但我可能完全错了。我刚刚用EJB3+JPA测试了这一点,并得到了您在获取实体的方法位于不同事务上下文时描述的延迟初始化问题


编辑:正如baba在评论中所说,更好的解决方案可能是通过HQL/Criteria(HQL中的fetch join子句)进行急切抓取,或者不太可取,在返回之前使用Hibernate.initialize。

我的猜测是,当您从获取实体的方法返回并开始遍历实体时,您已经处于不同的事务上下文中,从而导致延迟初始化问题;如果您使用的是DAO,请尝试将这两种方法设置为同一事务(即根据需要设置它们)

但我可能完全错了。我刚刚用EJB3+JPA测试了这一点,并得到了您在获取实体的方法位于不同事务上下文时描述的延迟初始化问题


编辑:正如baba在评论中所说,更好的解决方案可能是通过HQL/Criteria(HQL中的fetch join子句)进行急切抓取,也可能是在返回之前使用Hibernate.initialize。

adir1我遇到了完全相同的问题。在我的例子中,这个问题是由包含延迟加载集合的实例以前被手动逐出(都在事务边界内)的事实引起的。

adir1我遇到了完全相同的问题。在我的例子中,这个问题是由包含延迟加载集合的实例以前被手动逐出(都在事务边界内)的事实引起的。

关于这个问题的年代,对于后代:

同样的问题也发生在我身上,因为我将实体缓存在内存中。在以后的事务中访问这些实体时会立即引发异常,这与第一次收集实体时不同。因此出现了会话丢失问题


通过设置适当的二级缓存来解决此问题

关于这个问题的年代,对于后代:

同样的问题也发生在我身上,因为我将实体缓存在内存中。在以后的事务中访问这些实体时会立即引发异常,这与第一次收集实体时不同。因此出现了会话丢失问题


通过设置适当的二级缓存来解决此问题

如果您正在尝试迭代集合,但已经超出了获取实体的事务的范围,那么如果之前未初始化代理,您将获得该结果。这很正常,对吗?有两种方法可以解决这个问题:一种是将抓取设置为“急切”(不推荐,因为用您自己的话来说,“在大多数情况下不需要”)。第二个选项是,当需要此集合时,在获取它的事务中初始化它,然后使用它。给你的建议是:尽量避免跨越事务边界。再说一次——我大脑中缺失的环节是“在同一个事务中”——我真的相信我仍然是,正如我在调用堆栈中看到的那样。也许我会尝试直接调试事务方面,看看我的假设是否错误。如果您试图迭代集合,但已经超出了获取实体的事务的范围,如果代理之前未初始化,您将得到该结果。这很正常,对吗?有两种方法可以解决这个问题:一种是将抓取设置为“急切”(不推荐,因为用您自己的话来说,“在大多数情况下不需要”)。第二个选项是,当需要此集合时,在获取它的事务中初始化它,然后使用它。给你的建议是:尽量避免跨越事务边界。再说一次——我大脑中缺失的环节是“在同一个事务中”——我真的相信我仍然是,正如我在调用堆栈中看到的那样。也许我会尝试直接调试事务方面,看看我的假设是否是错误的,谢谢你的努力——我真的希望有人熟悉Hibernate的这方面。因为当我访问惰性字段时,很明显我处于相同的事务上下文中,所以我不清楚它为什么认为会话已关闭。嗯,不确定这是否有帮助,但我的意思是您需要检查是否确实处于相同的事务中,尤其是如果实体是从另一个组件(即DAO)返回的;这个