Unable to evaluate the expression Method threw ‘org.hibernate.LazyInitializationException‘ exceptio

背景

Unable to evaluate the expression Method threw ‘org.hibernate.LazyInitializationException’ exception.如何解决?????

使用hibernate从一方获取多方信息的时候发生
这个异常与hibernate加载关联对象的2种方式有关,一个是懒加载方式,一个是立即加载方式.

在这里插入图片描述

方案

步骤1、

一个颗粒会有多个选项
一个颗粒聚合多个选项的时候加上注解
在这里插入图片描述

 @OneToMany(mappedBy = "contentGrain", cascade = CascadeType.ALL,fetch = FetchType.EAGER, orphanRemoval = true)
    private List<Option> option ;
    @Entity
    private static class Option {

        public Option(){};
}

@OneToMany: 表示一个实体类的一个属性与另一个实体类的多个实例关联。
mappedBy = “contentGrain”: 指定了另一个实体类中与当前属性关联的属性名,也就是当前实体类所拥有的外键属性的名称。这里的 “contentGrain” 是另一个实体类中的属性名。
cascade = CascadeType.ALL: 表示级联操作,当对当前实体类进行增删改操作时,会同时对关联的另一个实体类进行相应的操作,例如删除当前实体类的同时,也会删除关联的另一个实体类。
fetch = FetchType.EAGER: 表示在加载当前实体类时,同时也会加载关联的另一个实体类。(没有写这个是造成没有及时加载的原因)
orphanRemoval = true: 表示如果另一个实体类与当前实体类的关系断开,另一个实体类是否应该自动删除。如果设置为 true,表示应该自动删除;如果设置为 false,表示不应该自动删除。

步骤2:

多的中的外键(对应的是颗粒主键)上的注解:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

     // 外键,指向外部类
        @ManyToOne
//        @JoinColumn(name = "outer_id")
        @JoinColumn(name = "outer_id",referencedColumnName = "id")
        private ContentGrain contentGrain;

总结

乱用注解者亡

"org.hibernate.LazyInitializationException"异常通常发生在使用Hibernate的延迟加载(Lazy Loading)时,当在Session关闭后或者没有事务上下文的情况下,尝试访问未加载的延迟加载属性时会抛出此异常。

为了解决这个问题,有几种常见的方法:

启用延迟加载(Eager Loading):在查询数据库时,使用Hibernate的"fetch"或"join fetch"来立即加载关联的实体。这样可以避免延迟加载,将相关数据一起查询出来,避免在Session关闭后访问未加载的属性。但要注意,使用Eager Loading可能会导致性能问题,因为它会一次性加载所有相关数据。

在事务范围内加载属性:如果你确保在访问延迟加载属性时仍然在Hibernate的事务范围内,你可以通过打开事务或延长事务的生命周期来解决这个问题。确保延迟加载属性的访问发生在事务内部。

使用OpenSessionInView模式:在Web应用中,可以使用OpenSessionInView模式来延长Session的生命周期,从而避免LazyInitializationException异常。这种模式允许Session在整个请求周期内保持打开状态,直到请求处理完成。但要注意,这种方法也可能带来一些潜在的性能问题,应谨慎使用。

使用FetchType.SUBSELECT:在实体类的关联属性上,可以设置FetchType为SUBSELECT。这将使用子查询(Subselect)方式加载所有延迟加载的关联实体,从而避免在Session关闭后访问未加载的属性。

@Entity
public class ParentEntity {
    // other fields and annotations

    @OneToMany(fetch = FetchType.LAZY)
    @Fetch(FetchMode.SUBSELECT)
    private List<ChildEntity> children;

    // getters and setters
}

使用DTO(Data Transfer Object):在某些情况下,你可以考虑使用DTO来封装需要的数据,而不是直接使用Hibernate实体类。这样可以避免延迟加载问题,因为DTO对象不会受到Hibernate延迟加载的影响。
总的来说,解决"org.hibernate.LazyInitializationException"异常的方法取决于具体的业务需求和使用场景。在选择解决方案时,要考虑性能和代码质量,并根据具体情况做出适当的调整。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Circ.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值