可以LAZY
在 HQL 中使用LEFT JOIN FETCH
.
FROM Obj AS obj LEFT JOIN FETCH obj.otherObj WHERE obj.id = :id
是否也可以覆盖EAGER
?如何?
可以LAZY
在 HQL 中使用LEFT JOIN FETCH
.
FROM Obj AS obj LEFT JOIN FETCH obj.otherObj WHERE obj.id = :id
是否也可以覆盖EAGER
?如何?
我有一种情况,由于历史原因,我确实渴望在几个一对多的依赖项之间进行获取。多年来,许多地方都依赖它,因此很难关闭。然而,在某些情况下,急切的获取会造成阻碍:对于表上的每个较大的选择,它会为每个对象的每个集合生成 100 个小子查询。我找到了解决这个问题的方法,不是真正覆盖急切的提取,但对我来说同样有用:只需创建一个一次性执行所有子提取的查询。这将对数据库进行 1 次物理查询,而不是让休眠模式遍历依赖关系图并产生 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 Docs的这个片段中的限定符意味着您可以用 eager 覆盖lazy,但不能反过来:
如果您正在使用属性级别的惰性获取(使用字节码检测),则可以强制 Hibernate 立即使用 fetch all properties 在第一个查询中获取惰性属性。
不同寻常的是,如果您使用 Criteria API 从渴望变为懒惰,看起来您可以。只需调用setFetchMode(FetchMode.LAZY)
相关的加入即可。