Hibernate Child Collection Limited when using Left Join in Criteria

When using sleep criteria, simply changing the connection type affects the results of the child collections of the root class of the domain.

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

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

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

Using the following hibernation criteria returns 1 parent row, and access to the results of the child collection returns two rows:

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, 1 parent row is returned, but when accessing the child collection, only the corresponding child row is returned.

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

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

  • EDIT 3/24: Corrected data *
+4
source share
2 answers

This issue is described here and apparently fixed in Hibernate 3.6

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

+1
source

I tried this: when doing this request, and then getting a call to parent.getChildren (), then:

  • LEFT JOIN: one query is executed containing the parent and one corresponding child after calling getChildren ()
  • INNER_JOIN: 2 queries are executed: one to find parents with matching children, and the other when calling getChildren ()

So, it seems that when LEFT_JOIN is called, the children (in this case the corresponding children) are selected EAGERLY, and the Parent children's collection is already full. For INNER_JOIN, however, this collection is marked as a proxy and is initialized when getChildren () is called; this second query, of course, will no longer take into account the restriction by name and simply select all the children for the parent.

This is like β€œinside” hibernation, which means that the type of connection will affect how hibernate processes the results. Although the generated SQL between the left and inner joins is slightly different (in my test, parent.id and child.id were twice in the select clause), the results returned when SQL was run in the database browser are the same.

I am not experienced enough to determine if this error is or not, but it does not look like it.

0
source

Source: https://habr.com/ru/post/1336857/


All Articles