HQL:从 Eager 表中获取连接集合

发布于 2024-09-15 08:24:45 字数 832 浏览 2 评论 0原文

我有四个表:

RootNode // Will return multiple root nodes 
SubNode // Will return one sub node per root node
SubNodeChildren1 // Will return multiple for each sub node
SubNodeChildren2 // Will return multiple for each sub node

以及一个类似的实体结构:

RootNode -> SubNode -> SubNodeChildren1
                    -> SubNodeChildren2

我需要一个查询来返回表中的所有 RootNodes 及其 SubNodeSubNode儿童初始化。 SubNode 是急切获取的,但 SubNode 子节点是惰性获取的。

我知道如何编写一个查询来LEFT OUTER JOIN FETCH表的直接子级并相应地初始化它们。但是,我不知道如何获取从顶级表中急切获取的表的子项。

我尝试过类似的操作:

SELECT rn FROM RootNode AS rn LEFT OUTER JOIN FETCH rn.SubNode.SubNodeChildren1

但是,这总是给我一个错误,表明所有者不是 SELECT 的一部分。

非常感谢任何帮助。

I have four tables:

RootNode // Will return multiple root nodes 
SubNode // Will return one sub node per root node
SubNodeChildren1 // Will return multiple for each sub node
SubNodeChildren2 // Will return multiple for each sub node

and a similar entity structure:

RootNode -> SubNode -> SubNodeChildren1
                    -> SubNodeChildren2

I need one query that will return all the RootNodes in the table with its SubNode and SubNode children initialized. The SubNode is eagerly fetched, but the SubNode children is lazy fetched.

I know how to write a query that will LEFT OUTER JOIN FETCH the immediate children of a table and initialize them accordingly. However, I have no idea of how to grab the children of a table that is eagerly fetched from the top-level table.

I have tried something like:

SELECT rn FROM RootNode AS rn LEFT OUTER JOIN FETCH rn.SubNode.SubNodeChildren1

but, this always gives me an error that the owner is not part of the SELECT.

Any help is greatly appreciated.

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

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

发布评论

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

评论(2

反目相谮 2024-09-22 08:24:45

这是 Hibernate 参考

我们可能需要别名的唯一原因是如果我们递归地连接获取进一步的集合

这意味着您的查询应该重写为

select distinct 
    rn
from
    RootNode rn
left join fetch 
    rn.subNode sn
left join fetch 
    sn.subNodeChildren

您可以

禁用默认 subNode fetch=FetchType.EAGER 并只检索什么你确实想要使用 HQL 查询 - 它(HQL 查询)有效地覆盖关联和集合的映射文件的外连接和惰性声明(Hibernate 参考文档)。这种方法得到了《POJO in Action》一书的支持。

或者启用 SubNodeChildren 的集合作为 fetch=FetchType.EAGER

以下内容摘自 Hibernate FAQ(该链接已被禁用(据我所知),但我在消失之前已保存)

在 MVC 应用程序中,如何我们能否确保当视图尝试访问所有代理和惰性集合时都会初始化它们?

一种可能的方法是在转发到视图时保持会话打开(并且事务未提交)。例如,在 servlet 过滤器中呈现视图后,会话/事务将被关闭/提交(另一个示例是在 Maverick 中使用 ModelLifetime.discard() 回调)。这种方法的一个困难是确保在渲染视图时发生异常时关闭/回滚会话/事务。

...

另一种方法是使用 Hibernate.initialize() 简单地强制初始化所有需要的对象。这通常比听起来更简单。

Here goes Hibernate reference

The only reason we might need an alias is if we are recursively join fetching a further collection

Which implies your query should be re-written as

select distinct 
    rn
from
    RootNode rn
left join fetch 
    rn.subNode sn
left join fetch 
    sn.subNodeChildren

You can either

disable default subNode fetch=FetchType.EAGER and just retrieve what you really want by using HQL query - It (HQL query) effectively overrides the outer join and lazy declarations of the mapping file for associations and collections (Hibernate reference documentation). This approach is supported by POJO in Action book.

or enable the collection of SubNodeChildren as fetch=FetchType.EAGER

The following has been extracted from the Hibernate FAQ (The link has been disabled (As far as i know) but i have saved before disappearing)

In an MVC application, how can we ensure that all proxies and lazy collections will be initialized when the view tries to access them ?

One possible approach is to leave the session open (and transaction uncommitted) when forwarding to the view. The session/transaction would be closed/committed after the view is rendered in, for example, a servlet filter (another example would by to use the ModelLifetime.discard() callback in Maverick). One difficulty with this approach is making sure the session/transaction is closed/rolled back if an exception occurs rendering the view.

...

Another approach is to simply force initialization of all needed objects using Hibernate.initialize(). This is often more straightforward than it sounds.

两仪 2024-09-22 08:24:45

为了使查询正常工作,我必须对急切的实体执行 INNER JOIN FETCH 而不是 LEFT OUTER JOIN FETCH

SELECT rn FROM RootNode AS rn INNER JOIN FETCH rn.SubNode AS sn LEFT OUTER JOIN FETCH sn.SubNodeChildren1 LEFT OUTER JOIN FETCH sn.SubNodeChildren2 ...

说实话,我仍然不太确定为什么它与 INNER JOIN FETCHLEFT OUTER JOIN FETCH 一起使用,但它绝对按照我需要的方式工作。

In order to get the query working, I had to do an INNER JOIN FETCH instead of a LEFT OUTER JOIN FETCH on the eager entity:

SELECT rn FROM RootNode AS rn INNER JOIN FETCH rn.SubNode AS sn LEFT OUTER JOIN FETCH sn.SubNodeChildren1 LEFT OUTER JOIN FETCH sn.SubNodeChildren2 ...

To be honest, I'm still not exactly sure why it's working with an INNER JOIN FETCH vs a LEFT OUTER JOIN FETCH, but it definitely is working exactly as I need it to.

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