Результаты API Hibernate Criteria не соответствуют результатам HQL для выборки из левого соединения - PullRequest
1 голос
/ 23 июня 2011

У меня есть две простые модели:

class Parent {
   Long id; //auto generated sequence and primary key
   String name;
   Set<Child> children;
}

class Child {
  String name;
  Long parent_id; //foreign key
}

У меня hql-запрос, подобный следующему:

FROM Parent p
  left join fetch p.children as children
WHERE p.name = 'John'

'children' - это набор (набор) модели 'Child' вРодительская модель.

Если у «Джона» есть 2 дочерних элемента, в результате вышеприведенного запроса я получу список из 2 родительских элементов (с одинаковой ссылкой), каждый из которых имеет 2 дочерних элементов, выполнив один запрос.

Я пытаюсьчтобы достичь того же с помощью API Criteria, как показано ниже:

Criteria c = session.createCriteria(Parent.class);
c.setFetchMode("children", FetchMode.JOIN);
c.createCriteria("children", Criteria.LEFT_JOIN);
c.add(Restrictions.eq("name", "John"));
c.scroll();

С помощью приведенного выше кода я получаю список из 2 родительских экземпляров (одна и та же ссылка) только с одним дочерним элементом (вместо ожидаемого 2), выполняющим одинSQL запрос

Что я делаю не так в API?Когда я вижу сгенерированный sql, это то же самое.

Ответы [ 2 ]

1 голос
/ 01 мая 2014

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

Она была исправлена ​​в этой проблеме Hibernate , но наши критерии все еще возвращали неполные дочерние коллекции в прокручиваемых результатах.Я обнаружил, что в классе Loader есть некоторая логика, которая решает, использовать ли FetchingScrollableResultsImpl для правильной обработки строк, а в CriteriaLoader этого не происходит, потому что needsFetchingScroll() всегда возвращает false.Однако QueryLoader использует его, когда используется выборка соединения, поэтому преобразование наших Критериев в HQL решило эту проблему для нас.

Я намерен сообщить об ошибке в Hibernate для реализации CriteriaLoader.needsFetchingScroll().

0 голосов
/ 23 июня 2011

У меня похожая ситуация, и вот код, который эквивалентен (по крайней мере, в моей ситуации):

Criteria c = session.createCriteria(Parent.class);
c.setFetchMode("children", FetchMode.JOIN);
c.add(Restrictions.eq("name", "John"));

List<Parent> list = c.list();
Iterator<Parent> iter = list.iterator();

У меня такое впечатление, что строка c.scroll(); вызывает поведение, аналогичное c.setResultTransformer( Criteria.DISTINCT_ROOT_ENTITY );

...