我有四个表:
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与它在表SubNode和SubNode孩子初始化。该SubNode是预先抓取,但SubNode孩子们是懒牵强。
RootNodes
SubNode
我知道如何编写查询,将查询LEFT OUTER JOIN FETCH表的直接子级并相应地对其进行初始化。但是,我不知道如何获取从顶层表急切获取的表的子级。
LEFT OUTER JOIN FETCH
我已经尝试过类似的东西:
SELECT rn FROM RootNode AS rn LEFT OUTER JOIN FETCH rn.SubNode.SubNodeChildren1
但是,这总是给我一个错误,即所有者不是SELECT的一部分。
任何帮助是极大的赞赏。
Hibernate参考
我们可能需要别名的唯一原因是, 如果我们以递归方式加入以获取其他集合
这意味着您的查询应重写为
select distinct rn from RootNode rn left join fetch rn.subNode sn left join fetch sn.subNodeChildren
你可以
禁用默认子节点fetch = FetchType.EAGER并通过使用HQL查询检索您真正想要的内容-它(HQL查询)有效地 覆盖了关联和集合的映射文件的外部联接和惰性声明 (Hibernate参考文档)。“行动”书中的POJO支持此方法。
或将SubNodeChildren的集合启用为fetch = FetchType.EAGER
以下是从Hibernate FAQ中提取的(该链接已被禁用(据我所知),但是我在消失之前已保存)
在MVC应用程序中,当视图尝试访问它们时,如何确保所有代理和惰性集合将被初始化?
一种可能的方法是在转发到视图时使会话保持打开状态(并且事务未提交)。在例如通过servlet过滤器呈现视图后,将关闭/提交会话/事务(另一个示例将使用Maverick中的ModelLifetime.discard()回调)。这种方法的一个难题是,如果在呈现视图时发生异常,则确保会话/事务被关闭/回滚。
…
另一种方法是简单地使用Hibernate.initialize()强制初始化所有需要的对象。这通常比听起来容易得多。