通过 HQL 的 Hibernate ScrollableResults 需要为每个关联获取左连接
Posted
技术标签:
【中文标题】通过 HQL 的 Hibernate ScrollableResults 需要为每个关联获取左连接【英文标题】:Hibernate ScrollableResults via HQL requires left join fetch for every association 【发布时间】:2012-11-04 12:18:29 【问题描述】:希望一些 Hibernate 大师可以提供帮助。
我有一个如下所示的对象结构:
class Customer
private Stuff1 stuff1;
private Stuff2 stuff2;
// Bazillion other fields
class Report
private Customer customer;
private String uniqueBatchId;
// Bazillion other fields
class AbstractSpecialReport
private Report report;
//Bunch of other fields
class SpecialReport extends AbstractSpecialReport
private List<ReportParts> reportParts;
这三个都被注释为 Hibernate 实体,所有关联都是默认的(使用 Hibernate 3.2,所以默认情况下应该是惰性的。
我想使用这个 HQL 来获得结果,使用 ScrollableResults
。我已经完成了所需的咒语以使结果集流式传输。
select srpt
from SpecialReport as srpt
left join fetch srpt.report as rpt
left join fetch rpt.customer as cst
left join fetch cst.stuff1
left join fetch cst.stuff2
where rpt.uniqueBatchId = :batchId
但我得到“java.sql.SQLException:流式传输结果集 com.mysql.jdbc.RowDataDynamic@633f8d4f 仍然处于活动状态。当任何流式传输结果集打开并在给定连接上使用时,不会发出任何语句。确保在尝试更多查询之前,您已在任何活动的流式传输结果集上调用了 .close()。"
我有 sql 查询登录,我可以清楚地看到它试图在报告中获取不相关的属性 它向前滚动。
所以我开始发展我的 HQL 以包含这些领域。
现在看起来像
select srpt
from SpecialReport as srpt
left join fetch srpt.report as rpt
left join fetch rpt.customer as cst
left join fetch rpt.field1
left join fetch rpt.field2
left join fetch rpt.field3
left join fetch rpt.field4 as child
-- now field 4 was an object that also has fields that are associations.
left join fetch child.field1
left join fetch child.field2
-- ad nauseum, this keeps going down the object tree
left join fetch cst.stuff1
left join fetch cst.stuff2
where rpt.uniqueBatchId = :batchId
即使有大约 25 个连接,我仍然有更多正在加载的字段导致相同的异常。
我可以继续手动遍历图表,但这需要很长时间,我觉得这不应该是必要的。查看 Hibernate 代码,滚动调用的 TwoPhaseLoad
似乎试图初始化对象中的所有代理和延迟加载的字段,这必然打破了滚动运行时不执行其他 sql 查询的要求。这对任何人来说都有意义吗?
【问题讨论】:
【参考方案1】:默认情况下,XxxToOne 关联是渴望的。如果您不希望 Hibernate 急切地加载它们,请将它们注释为惰性。
而且,SpecialReport 就是 Report,所以下面的 join 没有多大意义:
from SpecialReport as srpt
left join fetch srpt.report as rpt
【讨论】:
那是我的代码草图中的一个错误,SpecialReport 实际上并没有扩展 Report。我会检查 *ToOne 关联,但没有意识到它们是 Eager。以上是关于通过 HQL 的 Hibernate ScrollableResults 需要为每个关联获取左连接的主要内容,如果未能解决你的问题,请参考以下文章
[Hibernate] 通过 properties 类和 hql 语句进行动态查询