【问题标题】:Hibernate Child Collection Limited When Using Left Join in Criteria在条件中使用左连接时 Hibernate Child Collection Limited
【发布时间】:2011-06-14 19:01:58
【问题描述】:

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

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

家长 |编号 |姓名 | | 1 |家长 1 | 孩子 |编号 | parent_id |姓名 | | 1 | 1 |孩子1 | | 2 | 1 |孩子2 |

使用以下休眠条件返回 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:固定数据 *

【问题讨论】:

  • 伙计,我所有的知识都告诉我,内部连接应该只获取一行。我想你这里有事。我会将其添加为书签,以便遵循我所缺少的内容。如果我是,我会非常感谢你。
  • Child2 上的父 ID 是否错误?是 1 吗?
  • @MikelRascher - 是的,Child2 的父 ID 错误。我现在已经解决了。

标签: hibernate criteria hibernate-criteria


【解决方案1】:

这里描述了这个问题,似乎在 Hibernate 3.6 中已修复

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

【讨论】:

    【解决方案2】:

    我已经试过了: 执行此查询并随后调用 parent.getChildren() 时:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2012-08-28
      • 2016-03-10
      • 1970-01-01
      • 1970-01-01
      • 2011-02-19
      • 2022-11-10
      • 2021-10-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多