Hibernate Criteria API 结果与左连接获取的 HQL 结果不匹配
我有 2 个简单的模型:
class Parent {
Long id; //auto generated sequence and primary key
String name;
Set<Child> children;
}
class Child {
String name;
Long parent_id; //foreign key
}
我有一个像这样的 hql 查询:
FROM Parent p
left join fetch p.children as children
WHERE p.name = 'John'
“children”是父模型中“Child”模型的集合(集)。
如果“John”有 2 个孩子,则上述查询的结果通过执行单个查询为我提供 2 个父母(相同参考)的列表,每个父母有 2 个孩子。
我试图通过 Criteria API 实现相同的目标,如下所示:
Criteria c = session.createCriteria(Parent.class);
c.setFetchMode("children", FetchMode.JOIN);
c.createCriteria("children", Criteria.LEFT_JOIN);
c.add(Restrictions.eq("name", "John"));
c.scroll();
使用上面的代码,我在执行单个 sql 查询时获得了 2 个父实例(相同的引用)的列表,其中只有 1 个子元素(而不是预期的 2 个)。
我在 api 中做错了什么?当我看到生成的sql时,它是一样的。
I have 2 simple models:
class Parent {
Long id; //auto generated sequence and primary key
String name;
Set<Child> children;
}
class Child {
String name;
Long parent_id; //foreign key
}
I have a hql query like this:
FROM Parent p
left join fetch p.children as children
WHERE p.name = 'John'
'children' is a collection (set) of 'Child' model in Parent model.
If 'John' has 2 children, result of above query gives me list of 2 Parents (same reference) each with 2 children by executing a single query.
I am trying to achieve the same via Criteria API like below:
Criteria c = session.createCriteria(Parent.class);
c.setFetchMode("children", FetchMode.JOIN);
c.createCriteria("children", Criteria.LEFT_JOIN);
c.add(Restrictions.eq("name", "John"));
c.scroll();
With above code, I get the list of 2 parent instances (same reference) with only 1 child element (instead of expected 2) bu executing a single sql query.
What am I doing wrong in api? When I see the generated sql, it is same.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我遇到了同样的问题,在通过 Hibernate 代码进行调试后,我认为这是一个 Hibernate bug,而不是您做错的任何事情。
它已在 此 Hibernate 问题中得到修复,但我们的 Criteria 仍然以可滚动方式返回不完整的子集合结果。我发现在
Loader
类中,有一些逻辑决定是否使用FetchingScrollableResultsImpl
来正确处理行,而在CriteriaLoader
上它永远不会这样做因为needsFetchingScroll()
总是返回 false。然而,QueryLoader
在使用连接获取时确实会使用它,这就是为什么将我们的 Criteria 转换为 HQL 为我们解决了这个问题。我打算向 Hibernate 提交一个错误来实现
CriteriaLoader.needsFetchingScroll()
。I had the same issue, and after debugging through the Hibernate code I think it's a Hibernate bug rather than anything you're doing wrong.
It was fixed in this Hibernate issue, but our Criteria was still returning incomplete child collections in scrollable results. I found that in the
Loader
class there's some logic that decides whether to use theFetchingScrollableResultsImpl
to handle the rows properly, and onCriteriaLoader
it never does becauseneedsFetchingScroll()
always returns false. HoweverQueryLoader
does use it when a join fetch is used, which is why converting our Criteria into HQL fixed the issue for us.I intend to file a bug with Hibernate to implement
CriteriaLoader.needsFetchingScroll()
.我有类似的情况,这是等效的代码(至少在我的情况下):
我的印象是该行
c.scroll();
强制执行与c.setResultTransformer( Criteria.DISTINCT_ROOT_ENTITY );
类似的行为I have a similar situation, and here is the code that is equivalent (at least in my situation):
I have the impression that the line
c.scroll();
forces a similar behavior toc.setResultTransformer( Criteria.DISTINCT_ROOT_ENTITY );