使用 hibernate.enable_lazy_load_no_trans 解决 Hibernate Lazy-Init 问题 [英] Solve Hibernate Lazy-Init issue with hibernate.enable_lazy_load_no_trans

查看:30
本文介绍了使用 hibernate.enable_lazy_load_no_trans 解决 Hibernate Lazy-Init 问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直遭受臭名昭著的休眠异常

I have been suffering from infamous hibernate exception

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

现在社区正在欢呼

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

说它解决了问题,但谨慎使用.

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

What they mean by use it with caution? What this property actually does?

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

Please give me any insights. Thanks in advance.

推荐答案

这种方法的问题是你可以有 N+1 效果.

The problem with this approach is that you can have the N+1 effect.

假设您有以下实体:

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

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

If you have a report that returns 10K of persons, and if in this report you execute the code person.getOrderList() the JPA/Hibernate will execute 10K of queries. This is the N+1 effect, you will have no control about all the queries that will be executed.

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

Imagine now that Order is like below:

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

想象一下,现在您对 person.getOrderList() 进行了迭代,并且对于每个 Order order,您将执行一个 order.getEmailSentList()代码>.你现在能看出问题吗?

Imagine now that you have a iteration with the person.getOrderList() and for every Order orderyou will do a order.getEmailSentList(). Can you see the problem now?

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

For LazyInitializationException you can have some solutions:

  • 使用 OpenInSessionInView 方法.您需要创建一个 WebFilter 来打开和关闭事务.问题在于 N+1 效应.
  • 使用 hibernate.enable_lazy_load_no_trans 配置,这是一个休眠状态,如果需要,您将无法将您的项目移植到其他 JPA 提供程序.您也可以拥有 N+1 效果.
  • 使用名为 PersistenceContext Extended 的 EJB 功能.有了这个,您将保持多个事务的上下文打开.问题是:可能发生 N+1 效应,使用大量服务器内存(实体将保持管理)
  • 在查询中使用 FETCH.使用这种方法,您可以执行 JPQL/HQL,例如:select p from Person p join fetch p.orderList.使用此查询,您将从数据库加载您的列表,并且不会有 N+1 效果.问题是您需要为每种情况编写一个 JPQL.
  • Use the OpenInSessionInView approach. You will need to create a WebFilter that will open and close the transaction. The problem with is the N+1 effect.
  • Use the hibernate.enable_lazy_load_no_trans configuration, that is a hibernate and you will not be able to port your project to other JPA provider if needed. You also can have the N+1 effect.
  • Use the EJB feature named PersistenceContext Extended. With this you will keep the context opened of several transactions. The problems are: N+1 effect can happen, use a lot of server memory (entities will stay managed)
  • Use the FETCH in the query. With this approach you could do a JPQL/HQL like: select p from Person p join fetch p.orderList. With this query you will have your list loaded from the database and will not have the N+1 effect. The problem is that you will need to write a JPQL for each case.

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

If you still have any problem, check these links:

这篇关于使用 hibernate.enable_lazy_load_no_trans 解决 Hibernate Lazy-Init 问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆