背景
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"异常的方法取决于具体的业务需求和使用场景。在选择解决方案时,要考虑性能和代码质量,并根据具体情况做出适当的调整。