使用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)。
答案 0 :(得分:1)
这里描述了这个问题,似乎在Hibernate 3.6中已经修复了
答案 1 :(得分:0)
我试过这个: 执行此查询时,然后调用parent.getChildren()然后:
所以看来,在调用LEFT_JOIN时,子项(在这种情况下是匹配的子项)被EAGERLY获取,并且已经填充了Parent的子集合。 但是对于INNER_JOIN,此集合被标记为代理并在调用getChildren()时被初始化;第二个查询当然不再考虑名称的限制,只会为父母提取所有子项。
这似乎发生在'内部'hibernate中,这意味着连接类型将影响hibernate如何处理结果。虽然左连接和内连接之间生成的SQL稍有不同(在我的测试中,parent.id和child.id在select子句中是两次),但在DB浏览器中运行SQL时返回的结果是相同的。
我没有足够的经验来确定这是否是一个错误,但它不像是一个。