异常展示
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: ****, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:582)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:201)
at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:145)
at org.hibernate.collection.internal.PersistentBag.size(PersistentBag.java:261)
问题原因
触发延迟加载的时候,session已经失效
延迟加载原理
通过cglib对目标Entity实现代理,针对配置了延迟加载的属性,修改对应get方法的逻辑,植入延迟加载逻辑
解决方式
- 不使用延迟加载
- 延迟加载的时候session活跃
我们本来就想使用延迟加载来提高性能的,不使用延迟加载只是你逃避问题的方式!!要用延迟加载的地方必须用它!!
如何让延迟加载时session活跃
web项目
在springboot环境下,打开以下配置即可
spring.jpa.open-in-view=true
这个配置会通过WebMvcConfigurer配置一个OpenEntityManagerInViewInterceptor拦截器
而这个拦截器的作用。。我们看他的注释就知道了
就是处理请求的全程都能获取到EntityManager,其实就是能获取到session的意思。
普通提供dubbo服务的项目
在接口方法上加上@Transactional注解即可。
@Override
@Transactional(rollbackFor = Exception.class)
public List<XXDTO> getAllXX() {
List<XXEntity> result = xXQueryRepository.findAll();
return XXConverter.INSTANCE.entityListToDTOList(result);
}
@Transactional会保证在所注解方法作用域内session都生效
网友评论