在条件中使用 Left Join 时 Hibernate Child Collection 受到限制

发布于 2024-10-13 18:18:27 字数 990 浏览 8 评论 0原文

当使用休眠标准时,仅更改连接类型就会影响根域类的子集合的结果。

例如,让类 Parent 与类 Child 具有一对多关系,并具有以下数据:

Parent 
| id | Name     |
|  1 | Parent 1 |

Child
| id | parent_id | Name   |
|  1 |         1 | Child1 |
|  2 |         1 | Child2 |

使用以下休眠条件返回 1 个父行,并且访问子集合会返回两行:

session.createCriteria(Parent.class)
    .createCriteria('child', CriteriaSpecification.INNER_JOIN)
    .add( Restrictions.eq( 'name', 'Child1' ) )
    .list()

但是,当更改时上面的代码使用左连接,返回1个父行,但访问子集合时仅返回匹配的子行。

session.createCriteria(Parent.class)
    .createCriteria('child', CriteriaSpecification.LEFT_JOIN)
    .add( Restrictions.eq( 'name', 'Child1' ) )
    .list()

为什么会出现这种副作用呢?我发现了一些关于根据您的预期结果使用或避免这种副作用的讨论,但没有任何关于它为什么存在以及是否是有意为之的讨论。最接近的直接问题是一个陈旧的缺陷(http://opensource.atlassian.com /projects/hibernate/browse/HHH-3872)。

  • 编辑 3/24:固定数据 *

When using hibernate criteria just altering the join type affects the results of the child collections of the root domain class.

For instance, having class Parent have a one-to-many relationship with class Child with the following data:

Parent 
| id | Name     |
|  1 | Parent 1 |

Child
| id | parent_id | Name   |
|  1 |         1 | Child1 |
|  2 |         1 | Child2 |

Using the following hibernate criteria returns the 1 parent row, and accessing the child collection results in the two rows being returned:

session.createCriteria(Parent.class)
    .createCriteria('child', CriteriaSpecification.INNER_JOIN)
    .add( Restrictions.eq( 'name', 'Child1' ) )
    .list()

However, when changing the above code with a left join, the 1 parent row is returned, but only the matching child row is returned when accessing the child collection.

session.createCriteria(Parent.class)
    .createCriteria('child', CriteriaSpecification.LEFT_JOIN)
    .add( Restrictions.eq( 'name', 'Child1' ) )
    .list()

Why does this side-effect occur? I found a few discussions about using or avoiding this side-effect depending on your intended result, but nothing about why it is there in the first place and whether it was intended. The closest direct question is an old stale defect (http://opensource.atlassian.com/projects/hibernate/browse/HHH-3872).

  • EDIT 3/24: Fixed data *

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

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

发布评论

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

评论(2

坠似风落 2024-10-20 18:18:27

这个问题在这里描述,似乎在 Hibernate 3.6

https://hibernate.onjira.com 中得到了修复//浏览/HHH-2049

This problem is described here and seems to be fixed in Hibernate 3.6

https://hibernate.onjira.com//browse/HHH-2049

中二柚 2024-10-20 18:18:27

我已经尝试过这个:
当执行此查询并随后调用parent.getChildren()时,则:

  • LEFT JOIN:执行一个包含父级和一个匹配子级的查询,调用getChildren()时不执行后续查询
  • INNER_JOIN:执行2个查询:一个到在调用 getChildren() 时找到具有匹配子级的父级和另一个父级

因此,似乎在调用 LEFT_JOIN 时,会急切地获取子级(在本例中为匹配的子级),并且父级的子级集合已经填充。
然而,对于 INNER_JOIN,此集合被标记为代理,并在调用 getChildren() 时初始化;当然,第二个查询将不再考虑名称限制,而只是获取父级的所有子级。

这似乎确实发生在 hibernate“内部”,这意味着连接类型将影响 hibernate 处理结果的方式。尽管左连接和内连接之间生成的 SQL 略有不同(在我的测试中,select 子句中的parent.id 和 child.id 是两次),但在数据库浏览器中运行 SQL 时返回的结果是相同的。

我没有足够的经验来确定这是否是一个错误,但感觉不是一个错误。

I've tried this out:
when executing this query and afterwards getting calling parent.getChildren() then:

  • LEFT JOIN: one query is executed containing the parent and the one matching child, no subsequent query is executed when calling getChildren()
  • INNER_JOIN: 2 queries are executed: one to find the parents with matching childs and another when calling getChildren()

So it seems that when calling LEFT_JOIN the children (in this case the matching children) are EAGERLY fetched and the children collection of the Parent is already populated.
For the INNER_JOIN however this collection is marked as a proxy and is initialized when calling getChildren(); this second query will of course no longer take the restriction on name into account and will simply fetch all children for the Parent.

This does seem to happen 'inside' hibernate, meaning the join type will affect how hibernate treats the results. Although the generated SQL between a left and inner join differs slightly (in my test the parent.id and child.id were twice in the select clause) the results returned when running the SQL in a DB browser are the same.

I'm not experienced enough to determine if this a bug or not but it doesn't feel like one.

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