Hibernate Child Collection Limited When Using Left Join in Criteria

核能气质少年 提交于 2019-12-12 08:56:14

问题


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 *

回答1:


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

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




回答2:


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.



来源:https://stackoverflow.com/questions/4787002/hibernate-child-collection-limited-when-using-left-join-in-criteria

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!