Запрос гибернации не возвращает полный объект - PullRequest
1 голос
/ 27 января 2010

У меня есть список предметов. Каждый элемент имеет набор категорий. Я хочу захватить все предметы определенной категории. Эта часть проста. Часть, с которой у меня возникли проблемы, - это заставить мой запрос вернуть элемент со всеми его категориями, а не только с той, по которой я фильтрую.

session.createCriteria(Item.class)
        .createAlias("categories","category")
        .add(Restrictions.eq("category.name",categoryFilter))

Приведенный выше код возвращает элемент, но только с категорией, по которой я фильтрую. Можно ли как-то сказать фильтровать объект по этому ограничению, но вернуть полный объект, а не отфильтрованный? Я также пытался написать это на HQL с теми же результатами.

Ответы [ 4 ]

3 голосов
/ 30 января 2010

Похоже, что между FetchMode и createAlias ​​действительно есть какое-то неприятное взаимодействие, которое мне кажется ошибкой.

Это обсуждается на https://forums.hibernate.org/viewtopic.php?t=944439, когда один из разработчиков решительно заявил, что это правильное поведение и не будет исправлено.

Обсуждение также содержит потенциальные обходные пути.

Попробуйте использовать вложенный критерий вместо псевдонима:

session.createCriteria(Item.class)
   .createCriteria("categories")
       .add(Restrictions.eq("name",categoryFilter))

С коллекцией, отображенной как нетерпеливая, это, кажется, работает для меня. Не уверен в взаимодействии с использованием FetchMode по внешним критериям.

0 голосов
/ 02 апреля 2013

Другое решение заключается в использовании подзапроса Exists, чтобы FetchMode.JOIN также работал. (При этом используется DetachedCriteria, но критерии должны быть похожими)

DetachedCriteria criteria = session.createCriteria(Item.class, "i");
criteria.setFetchMode("categories", FetchMode.JOIN);

DetachedCriteria catCriteria = DetachedCriteria.forClass(Category.class, "category");
catCriteria.add(Restrictions.eq("name", categoryFilter));
catCriteria.add(Restrictions.eqProperty("category.id", "i.categoryId"));
criteria.add(Subqueries.exists(catCriteria.setProjection(Projections.property("category.id"))));

Надеюсь, это поможет кому-то еще, так как документы так трудно понять. Я также добавил github gist с дополнительными комментариями

0 голосов
/ 30 января 2010

Если это ошибка Я сообщал некоторое время назад : Мой обычный обходной путь - это только выбор идентификаторов соответствующих элементов, а затем выбор элементов с их категориями в последующем запросе:

List<Serializable> ids = session.createCriteria(Item.class)
    .createAlias("categories","category")
    .add(Restrictions.eq("category.name",categoryFilter))
    .setProjection(Projections.id())
    .list();

List<Items> items = session.createCriteria(Item.class)
    .add(Restrictions.in("id", ids)
    .createAlias("categories","category")
    .list();
0 голосов
/ 30 января 2010

Скорее всего, это не имеет ничего общего с использованием псевдонима и ограничения, но является просто результатом ленивого извлечения по умолчанию.

В вашем отображении Item у вас, вероятно, есть категории, для которых лениво выбирается выборка, что по умолчанию, и, как правило, хорошая идея.

Вы можете изменить это отображение на нетерпеливое, но это, вероятно, плохая идея.

Чтобы оставить извлечение по умолчанию ленивым, но с особенным желанием получить определенные критерии, вы можете установить там режим извлечения, с чем-то похожим на

session.createCriteria(Item.class)
    .setFetchMode("categories", FetchMode.EAGER)
    .createAlias("categories","category")
    .add(Restrictions.eq("category.name",categoryFilter))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...