gpt4 book ai didi

java - 使用 hibernate.enable_lazy_load_no_trans 解决 Hibernate Lazy-Init 问题

转载 作者:IT老高 更新时间:2023-10-28 20:30:28 36 4
gpt4 key购买 nike

我一直在遭受臭名昭著的 hibernate 异常

org.hibernate.LazyInitializationException: could not initialize proxy - no Session

现在社区为之欢呼

<property name="hibernate.enable_lazy_load_no_trans" value="true"/>

说它可以解决问题,但谨慎使用

谨慎使用是什么意思?这个属性实际上是做什么的?

请给我任何见解。提前致谢。

最佳答案

这种方法的问题是你可以产生 N+1 效应。

假设您有以下实体:

public class Person{
@OneToMany // default to lazy
private List<Order> orderList;
}

如果您有一个返回 10K 人的报告,并且如果您在此报告中执行代码 person.getOrderList() JPA/Hibernate 将执行 10K 的查询。这是 N+1 效应,您将无法控制将要执行的所有查询。

现在想象一下 Order 如下所示:

public class Order{
@OneToMany // default to lazy
private List<EmailSent> emailSentList;
}

现在想象一下,您有一个迭代 person.getOrderList()对于每个 Order order你会做一个order.getEmailSentList() .你现在能看出问题了吗?

对于 LazyInitializationException 你可以有一些解决方案:

  • 使用 OpenInSessionInView 方法。您将需要创建一个 WebFilter 来打开和关闭事务。问题在于 N+1 效应。
  • 使用 hibernate.enable_lazy_load_no_trans 配置,这是一种 hibernate ,如果需要,您将无法将您的项目移植到其他 JPA 提供程序。你也可以有 N+1 的效果。
  • 使用名为 PersistenceContext Extended 的 EJB 功能。这样,您将保持多个事务的上下文打开。问题是:可能会发生 N+1 效应,使用大量服务器内存(实体将保持托管状态)
  • 在查询中使用 FETCH。使用这种方法,您可以执行如下 JPQL/HQL:select p from Person p join fetch p.orderList .使用此查询,您将从数据库中加载您的列表,并且不会产生 N+1 效果。问题是您需要为每个案例编写一个 JPQL。

如果仍有问题,请查看以下链接:

关于java - 使用 hibernate.enable_lazy_load_no_trans 解决 Hibernate Lazy-Init 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25362831/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com