记录一下今天在SpringBoot中遇到的LazyInitializationException问题

问题描述

今天学习SpringBoot,在随课写代码的时候遭遇一个异常:

org.hibernate.LazyInitializationException: could not initialize proxy [com.law.Entity.ProductCategory#1] - no Session

我感觉下面的信息都不关键,这句大概就够了。贴一下完整代码,万一有用呢:
实体类:

@Entity
public class ProductCategory {
    //Category ID
    @Id
    @GeneratedValue
    private Integer categoryId;
    //Category Name
    private String categoryName;
    //Category Type Number
    private Integer categoryType;

    //此处省略getter、setter和一个toString方法
}

Repository接口 和 测试类:

public interface ProductCategoryRepository extends JpaRepository<ProductCategory, Integer> {
}
@RunWith(SpringRunner.class)
@SpringBootTest
public class ProductCategoryRepositoryTest {
    @Autowired
    private ProductCategoryRepository productCategoryRepository;

    @Test
    public void findOneTest(){
        ProductCategory productCategory = productCategoryRepository.getOne(1);
        System.out.println(productCategory);
    }
}

错误原因:

一开始怀疑是版本问题,因为我的idea在创建工程时只能使用2.x版本,我懒得去处理,于是就创建了2.x。但是后来我对比了之前运行成功过的SpringBoot项目,发现代码上没有什么差异,于是暂时排除了这一可能,但实际上还没有弄得特别明白。

后来在别的地方看到了转载自未知出处(并没有原文链接所以并不知道原文在哪里,至于是在哪看到的,忘了=,=)的一段文字:

因为 hibernate(这里是 Spring Data JPA ) 跟 spring 整合以后
hibernate 的 session 就交给 spring 管理了
请求进来的时候打开 session,请求完成的时候关闭 session
当我们想要使用懒加载去获取数据的时候
这时候原先的那个 session 已经关闭了
不能再获取数据了。

解决方案

网上有很多关于这个问题的解法,但是我看了很多问题都是出在有@OneToMany或相关注解的地方。
最终在我这里成功解决问题的有两种方法

第一种受启发于 这里

在配置文件中添加如下项:

spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true

大致明白意义是启动延迟加载,加上这个配置后可以正常输出结果。但是正如上面链接里提到的,这个方法在项目需要移植时可能会失效。

第二种

这是病入膏肓的时候突然想到的,大概是很早看到的某篇文章提到,如果子类如何如何,出现这种问题,那么需要为父类添加@Transactional注解。我想想我这也没有父类,于是我给测试方法加上了@Transactional注解,同样能解决问题。
记录一下今天在SpringBoot中遇到的LazyInitializationException问题_第1张图片

网上还有第三种解决方法,但是我这里运行一就报错

在配置文件中添加

spring.jpa.open-in-view=true

并没有解决问题……

总结

平常也不爱把笔记之类的发到CSDN上,这是第一次,希望做一个新尝试,如果不能有很好的效果就算了hhhh,希望各位大佬轻点下手。
我其实并不知道其中的原理具体是什么,今天就到此休息,明天再继续研究是怎么回事,如果有幸有大佬看到了,希望大佬能指出我的错误,并给出您的见解。

其实我还是很怀疑是不是版本的问题,但是我印象中我之前自己摸索着做的SpringBoot小工程没有出现过这些问题,代码中也没有添加注解,设置中也没有上述方法1中的配置。希望有懂的人能分享一下。

你可能感兴趣的:(记录一下今天在SpringBoot中遇到的LazyInitializationException问题)