2010-06-18 117 views

回答

3

Hibernate Docs这个片段限定符意味着你可以重写懒惰与渴望,而不是周围的其他方式:

如果你使用属性级别的懒惰 取(用字节码 仪器) ,有可能 强制Hibernate立即使用获取所有 属性来获取第一个查询 中的惰性 属性。

不同寻常的是,如果您使用Criteria API从急于变为懒惰,看起来可以。只需在相关联接中调用setFetchMode(FetchMode.LAZY)即可。

+1

它看起来像setFetchMode(FetchMode.LAZY)仍然有点热切地提取它们(即,它们不是由急切的连接提取,而是由n + 1在最初的SQL查询之后选择)。似乎没有办法完全覆盖EAGER设置。 – jsight 2010-11-05 18:33:53

+0

我有同样的经历。此注释的JavaDoc似乎存在争议(http://opensource.atlassian.com/projects/hibernate/browse/HHH-980),但无论使用SELECT还是LAZY,孩子仍然会抓取EAGER。不知道我是否做错了什么,或者是否存在Hibernate错误。 – atrain 2011-05-13 15:09:19

+0

'FetchMode.LAZY'也被弃用 – 2011-08-30 10:22:37

4

我有一种情况,由于历史原因,在几个一对多的依赖关系之间进行了热切的获取。多年来很多地方都依赖它,所以很难关闭。然而在某些情况下,渴望获取会阻碍:对于表中的每一个更大的选择,它都会为每个对象的每个集合产生100个小型子查询。我找到了解决这个问题的方法,并不是真的重写了渴望的获取,而是对我来说同样有用:只需创建一个能够一次执行所有子读取的单个查询。这将对数据库进行1次物理查询,而不是使用hibernate遍历依赖关系图并产生100个查询。

所以我代替

Query q = session.createQuery("from Customer c"); 

通过

Query q = session.createQuery("from Customer c " + 
           "left join fetch c.vats v " + 
           "left join fetch v.klMemos bk " + 
           "left join fetch bk.ferryKlMemos"); 

1客户有很多的增值税号,1增值税号码有许多klmemos等。旧的情况将首先取消客户,然后hibernate将开始逐个取回每个依赖集合。第二种形式会将所有内容加载到一个本地查询中,并且hibernate将查找它填充对象缓存中的渴望集合所需的全部内容。

注意这种方法还可以模拟配置为懒惰的集合的快速提取获取,因为您正在以热切(高效)的方式填充所有“懒惰”集合。