我可以在Hibernate中从FetchType.EAGER交换到FetchType.LAZY,而无需进行任何编码更改

时间:2018-07-20 10:21:54

标签: hibernate

我正在使用Hibernate 4.3.11

我在一堂课中使用

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

返回子集合

进行了一些性能分析,我认为这引起了我一个问题,我可以安全地将其恢复为

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

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

2 个答案:

答案 0 :(得分:0)

这取决于:通常不,您不能安全切换。 切换到此选项几乎可以肯定会导致org.hibernate.LazyInitializationException

出现一些问题

每次您的代码尝试获取某些数据时,都会引发此异常,但是此时不再获取您的实体,并且您已关闭连接。

即:

public class Person(){
    Address address;
}

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

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

由于我不了解您的课程,所以我将其概括化,但是希望它能使您了解问题所在。

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

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

这解决了org.hibernate.LazyInitializationException的问题,但再次造成了我认为您遇到的问题(慢速查询和繁重查询)。 每当他需要完成在调用时尚未提取的实体时,这将自动打开连接。

您可以找到一个很好的解释here

答案 1 :(得分:0)

嗨,您可以定义@OneToMany(fetch=FetchType.LAZY, cascade={CascadeType.ALL})

因此它不会获取子级数据。

如果您希望通过某种方法获取子数据,请编写hql查询以热切地获取带有子对象的对象

假设您具有一个在一对多关系中具有List<Address>的User对象。

"SELECT u FROM Users u " +
    "JOIN FETCH u.address  "