Hibernate Child Collection ограничивается при использовании левого соединения в критериях - PullRequest
4 голосов
/ 24 января 2011

При использовании критериев гибернации простое изменение типа объединения влияет на результаты дочерних коллекций класса корневого домена.

Например, наличие у класса Parent отношения один-ко-многим с классом Child сследующие данные:

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

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

При использовании следующих критериев гибернации возвращается 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: Фиксированные данные *

Ответы [ 2 ]

1 голос
/ 11 июля 2011

Эта проблема описана здесь и, кажется, исправлена ​​в Hibernate 3.6

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

0 голосов
/ 22 марта 2011

Я попробовал это: при выполнении этого запроса и последующем получении вызова parent.getChildren () затем:

  • LEFT JOIN: выполняется один запрос, содержащий родительский элемент и один соответствующий дочерний элемент,последующий запрос не выполняется при вызове getChildren ()
  • INNER_JOIN: выполняется 2 запроса: один для поиска родителей с совпадающими дочерними элементами и другой при вызове getChildren ()

Так что, похожечто при вызове LEFT_JOIN дочерние элементы (в данном случае совпадающие дочерние элементы) извлекаются EAGERLY, а коллекция дочерних элементов родительского элемента уже заполняется.Однако для INNER_JOIN эта коллекция помечается как прокси и инициализируется при вызове getChildren ();этот второй запрос, конечно, больше не будет учитывать ограничение имени и будет просто извлекать всех дочерних элементов для Parent.

Похоже, это происходит «внутри» hibernate, то есть тип соединения будет влиять на то, как обрабатывается hibernate.результаты, достижения.Хотя сгенерированный SQL между левым и внутренним объединением немного отличается (в моем тесте parent.id и child.id были дважды в предложении select), результаты, возвращаемые при запуске SQL в браузере БД, одинаковы.

У меня недостаточно опыта, чтобы определить, является ли это ошибкой или нет, но это не так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...