在标准中使用左连接时的Hibernate Child Collection Limited

当使用hibernate标准时,只是改变连接类型会影响根域类的子集合的结果。

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

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

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

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

  • 这个问题在这里描述,似乎在Hibernate 3.6中得到了解决

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


    我已经试过了这一点:当执行这个查询,然后调用parent.getChildren()然后:

  • LEFT JOIN:执行一个包含父项和一个匹配子项的查询,调用getChildren()时不执行后续查询。
  • INNER_JOIN:执行2个查询:一个在调用getChildren()时查找具有匹配子对象的父对象,
  • 所以看起来,当调用LEFT_JOIN时,孩子(在这种情况下是匹配的孩子)被EAGERLY提取并且Parent的子集合已经被填充。 然而,对于INNER_JOIN,这个集合被标记为代理并在调用getChildren()时被初始化; 这第二个查询当然不再考虑名称的限制,只会为父提取所有子代。

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

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

    链接地址: http://www.djcxy.com/p/6309.html

    上一篇: Hibernate Child Collection Limited When Using Left Join in Criteria

    下一篇: Hibernate criteria restriction on a property for all elements of a set