Hibernate:在HQL中覆盖映射的EAGER?

Ond*_*žka 18 hibernate hql eager lazy-evaluation fetch

可以LAZY使用HQL 覆盖LEFT JOIN FETCH.

FROM Obj AS obj LEFT JOIN FETCH obj.otherObj WHERE obj.id = :id
Run Code Online (Sandbox Code Playgroud)

是否也可以覆盖EAGER?怎么样?

gee*_*rt3 8

我有一种情况,由于历史原因,在几个一对多的依赖关系之间急切地获取.多年来,许多地方依赖它,因此很难关闭.但是在某些情况下,急切的提取会阻碍:对于表中的每个较大的选择,它会为每个对象的每个集合产生100个小子查询.我找到了解决这个问题的方法,并没有真正覆盖了渴望的提取,但对我来说同样有用:只需创建一个查询即可同时执行所有子提取.这将对数据库进行1次物理查询,而不是让hibernate遍历依赖图并生成100个查询.

所以我换了

Query q = session.createQuery("from Customer c");
Run Code Online (Sandbox Code Playgroud)

通过

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

1客户有很多增值税号,1个增值税号有很多klmemos等等.旧的情况将首先仅获取客户,然后休眠将开始逐个获取每个依赖的集合.第二种形式将在一个本机查询中加载所有内容,而hibernate将找到填充对象缓存中的eager集合所需的全部内容.

请注意,这种方法还可以模拟对配置为惰性的集合的快速急切获取,因为您以急切(高效)的方式填充所有"懒惰"集合.


sbl*_*ndy 4

Hibernate 文档中这段代码片段中的限定符意味着您可以用 eager 覆盖lazy,但反之则不然:

如果您使用属性级延迟获取(使用字节码检测),则可以强制 Hibernate 使用“获取所有属性”立即在第一个查询中获取延迟属性。

不同寻常的是,如果您使用 Criteria API 从急切转变为懒惰,那么您似乎可以做到这一点。只需调用setFetchMode(FetchMode.LAZY)相关的连接即可。