Hibernate Criteria API 结果与左连接获取的 HQL 结果不匹配

发布于 2024-11-16 12:49:35 字数 849 浏览 1 评论 0原文

我有 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 技术交流群。

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

发布评论

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

评论(2

最佳男配角 2024-11-23 12:49:35

我遇到了同样的问题,在通过 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 the FetchingScrollableResultsImpl to handle the rows properly, and on CriteriaLoader it never does because needsFetchingScroll() always returns false. However QueryLoader 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().

柏拉图鍀咏恒 2024-11-23 12:49:35

我有类似的情况,这是等效的代码(至少在我的情况下):

Criteria c = session.createCriteria(Parent.class);
c.setFetchMode("children", FetchMode.JOIN);
c.add(Restrictions.eq("name", "John"));

List<Parent> list = c.list();
Iterator<Parent> iter = list.iterator();

我的印象是该行
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):

Criteria c = session.createCriteria(Parent.class);
c.setFetchMode("children", FetchMode.JOIN);
c.add(Restrictions.eq("name", "John"));

List<Parent> list = c.list();
Iterator<Parent> iter = list.iterator();

I have the impression that the line
c.scroll(); forces a similar behavior to c.setResultTransformer( Criteria.DISTINCT_ROOT_ENTITY );

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