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

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

问题描述

  org.hibernate.LazyInitializationException:无法初始化代理 - 没有Session 

现在社区正在欢呼



< property name =hibernate.enable_lazy_load_no_transvalue =true/>



表示可以解决问题,但谨慎使用



谨慎使用它们意味着什么?这个属性实际上做了什么?



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

解决方案

这种方法的问题是您可以拥有N + 1效果。 b
$ b

想象一下你有以下实体:

  public class Person {
@OneToMany //默认为懒
private List< Order>订单;





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



现在想象一下订单如下所示:

  public class Order {
@OneToMany //默认为懒
private List< EmailSent> emailSentList;
}

现在想象一下,您已经对人进行了迭代.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,如:从Person p join fetch p.orderList 中选择p。使用此查询,您将从数据库加载列表,并且不会产生N + 1效应。问题是您需要为每种情况编写JPQL。
  • / p>


    I have been suffering from infamous hibernate exception

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

    Now the community is cheering over

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

    saying it solves the problem but USE IT WITH CAUTION.

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

    Please give me any insights. Thanks in advance.

    解决方案

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

    Imagine that you have the following entity:

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

    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.

    Imagine now that Order is like below:

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

    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?

    For LazyInitializationException you can have some solutions:

    • 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天全站免登陆