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

发布于 2024-09-06 20:30:48 字数 197 浏览 2 评论 0原文

可以使用 LEFT JOIN FETCH 覆盖 HQL 中的 LAZY

FROM Obj AS obj LEFT JOIN FETCH obj.otherObj WHERE obj.id = :id

是否也可以覆盖EAGER?如何?

It's possible to override LAZY in HQL using LEFT JOIN FETCH.

FROM Obj AS obj LEFT JOIN FETCH obj.otherObj WHERE obj.id = :id

Is it also possible to override EAGER? How?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蓝眼睛不忧郁 2024-09-13 20:30:48

我遇到过一种情况,由于历史原因,在几个一对多依赖关系之间进行了急切的获取。多年来,许多地方开始依赖它,因此很难关闭它。然而,在某些情况下,急切的获取会产生阻碍:对于表上的每个较大的选择,它都会为每个对象的每个集合生成数百个小子查询。我找到了一种方法来解决这个问题,并没有真正覆盖急切的获取,但对我来说同样有用:只需创建一个一次性执行所有子获取的查询。这将对数据库进行 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 将找到填充对象缓存中的急切集合所需的所有内容。

请注意,此方法还模拟配置为惰性集合的快速急切获取,因为您以急切(且高效)的方式填充所有“惰性”集合。

I had a situation that for historical reasons did eager fetch between several one-to-many dependencies. Over years many places came to depend on it so it was hard to turn off. However for some cases, the eager fetch was hindering: for every larger selection on the table, it would spawn 100s of small subqueries for each of the collections of each of the objects. I found a way to get around this, not really overriding the eager fetch, but for me just as useful: simply create a single query that does all the subfetches at once. This will make 1 physical query to the database, instead of having hibernate walk the dependency graph and spawn 100s of queries.

So I replaced

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

by

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 Customer has many VAT numbers, 1 VAT number has many klmemos and so on. The old situation would first fetch only the customers and hibernate would then start fetching each of the dependent collections one by one. The second form will load everything in one native query, and hibernate will find all it needs to populate the eager collections in the object cache.

Note this approach also simulates fast eager fetch for collections that are configured to be lazy, as you're populating all the "lazy" collections in an eager (and efficient) way.

最丧也最甜 2024-09-13 20:30:48

此片段中的限定符来自 Hibernate Docs 意味着您可以用 eager 覆盖懒惰,但反之则不然:

如果您使用的是属性级惰性
获取(使用字节码
仪器),可以
强制 Hibernate 获取惰性
第一个查询中的属性
立即使用 fetch all
属性。

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

The qualifier in this snippet from the Hibernate Docs implies that you can override lazy with eager, but not the other way around:

If you are using property-level lazy
fetching (with bytecode
instrumentation), it is possible to
force Hibernate to fetch the lazy
properties in the first query
immediately using fetch all
properties.

Unusually, it looks like you can if you use the Criteria API to go from eager to lazy. Just call setFetchMode(FetchMode.LAZY) on the relevant join.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文