首页 > 解决方案 > 在 Hibernate 中,我可以从 FetchType.EAGER 交换到 FetchType.LAZY 而不进行任何编码更改

问题描述

我正在使用休眠 4.3.11

在我使用的一类中

@OneToMany(fetch=FetchType.EAGER, cascade={CascadeType.ALL})

返回子集合

做了一些性能分析后,我认为这给我带来了问题,我可以安全地将其恢复为

@OneToMany(fetch=FetchType.LAZY, cascade={CascadeType.ALL})

无需对我的代码进行任何其他更改,或者不?

标签: hibernate

解决方案


这取决于:通常不,您无法安全切换。切换到这个几乎肯定会产生一些问题org.hibernate.LazyInitializationException

每次您的代码尝试获取一些数据时都会引发此异常,但随后您的实体不再被获取并且您有一个关闭的连接。

IE:

public class Person(){
    Address address;
}

在这种情况下,当您尝试获取时,yourPerson.getAddress().getStreet()您将得到上述异常。

为避免此异常,您需要做的是重写查询,并在每次yourPerson.getAddress().getStreet()调用和需要时将需要使用的项目提取到代码中,并避免在不需要时获取地址项目。

由于我不知道您的课程,因此我正在概括,但我希望它能让您了解问题出在哪里。

当我说“这取决于”时,我指的是休眠选项

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

这解决了 的问题org.hibernate.LazyInitializationException,但它再次产生了我认为您遇到的问题(缓慢而繁重的查询)。每次他需要感染调用时尚未获取的实体时,这都会自动打开连接。

你可以在这里找到一个很好的解释


推荐阅读