问题描述

org.hibernate.LazyInitializationException - no session

image.png
原因:查询数据库事务已经关闭,再去调用其内部属性时没有session(这里说的是数据库session,不是web session)

Spring框架中的数据库事务

image.png

已知解决方案

1、关闭LazyInitialization, 将fetch设成eager,可以在配置文件,也可注解

2、在spring boot的配置文件application.properties添加

spring.jpa.open-in-view=true

不建议使用 原因 -> What is this spring.jpa.open-in-view=true property in Spring Boot?

3、用spring 的OpenSessionInViewFilter,实现原理类似2

4、在spring boot的配置文件application.properties添加

spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true

5、在实体类上加@Proxy(lazy = false),

if you are using XML configuration: add default-lazy="false" to your element
if you are using annotation configuration: add @Proxy(lazy=false) to all your entity classes.

原文链接

6、2. 通过在查询中使用 fetch 的方式
通过再查询中使用 fetch,一次将相关数据查询出来,不会产生 N + 1 的影响。

继续使用上面的 用户-权限 的例子。先把 spring.jpa.properties.hibernate.enable_lazy_load_no_trans 这个配置去掉,然后在UserRepository 中添加如下方法:

@Query("from User u join fetch u.authorityList")
public User findOne(Long id);

测试类中的 queryUser 代码改为下面的:

@Test
public void queryUser() {
    User user = userRepository.findOne(2L);
    System.out.println(user);

    System.out.println(user.getAuthorityList());
}

进行查询,只会执行一条sql:

Hibernate: select user0_.id as id1_5_0_, authority2_.id as id1_3_1_, 
user0_.password as password2_5_0_, user0_.username as username3_5_0_, 
authority2_.name as name2_3_1_, authorityl1_.user_id as user_id1_6_0__, 
authorityl1_.authority_id as authorit2_6_0__ 
from user user0_ 
inner join user_authority authorityl1_ on user0_.id=authorityl1_.user_id 
inner join authority authority2_ on authorityl1_.authority_id=authority2_.id

通过 sql 可以看出,实际上就是使用了sql 里的 join 一次查询出来多条数据。
原文链接

附:Hibernate ORM使用文档 - 配置项

文章作者: Administrator
本文链接:
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 if(xyz!=null)
技术分享 jpa hibernate
喜欢就支持一下吧
打赏
微信 微信
支付宝 支付宝