我遇到过一种情况,我返回API响应(请求线程)并将任务委派给后台线程。在后台线程中,我调用hibernate的T getOne(ID id);
来获取一些信息,这导致
org.hibernate.LazyInitializationException:无法初始化代理-线程类中没有会话
但是,当使用JPA查询@Query("some query")
、本机查询@Query(value = "some query", native = true)
和JdbcTemplate执行DB操作时,它在后台线程中运行良好。
有人能帮我理解为什么会有这样的行为吗?
FYI。。我使用Spring Boot 1.4.2和Hibernate 5.0.11
T getOne(ID id)
依赖于执行实体延迟加载的EntityManager.getReference()
。因此,为了确保实体的有效加载,需要调用实体上的方法。
基本上,当线程需要初始化与另一个没有活动会话上下文的实体的延迟获取关联时,context.Hibernate
会抛出LazyInitializationException
,但找不到任何活动会话。你在任何关联中FetchType.EAGER
与你试图获取的对象有关联。但是,它可能会有自己的影响,比如每次尝试获取对象时都会执行不需要的查询。
最佳解决方案将使用Optional<T> findById(ID id)
。您可以使用obj.isPresent()
检查实体是否存在,然后继续。