我正在使用Hibernate 4.3.11
我在一堂课中使用
@OneToMany(fetch=FetchType.EAGER, cascade={CascadeType.ALL})
返回子集合
进行了一些性能分析,我认为这引起了我一个问题,我可以安全地将其恢复为
@OneToMany(fetch=FetchType.LAZY, cascade={CascadeType.ALL})
无需对我的代码进行任何其他更改?
答案 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 "