Выбор предела Критерии гибернации - PullRequest
2 голосов
/ 25 февраля 2011

Итак, у меня довольно сложный запрос, который я пытаюсь сделать с использованием Hibernate Criteria API.У меня есть следующие классы сущностей:

Код
Подарок
GiftVendor
GiftVendorStatus

со следующими отношениями:

Code 1 <> 1 Gift
Gift 1 <> * GiftVendor
GiftVendor 1 <> 1 GiftVendorStatus

Мне нужно создать запрос Criteria, который возвращает список объектов Code,но это ограничивает его только теми кодами, у которых есть Gift, у которого есть хотя бы один GiftVendor с GiftVendorStatus of Online.Вот код, который я использую для построения критериев:

Criteria base = CodeDao.getBaseCriteria();
base.createAlias("gift","gift");
base.createAlias("gift.giftVendor","giftVendor");
base.createAlias("giftVendor.giftVendorStatus","giftVendorStatus");
base.add(Restrictions.like("giftVendorStatus.description", "Online%"));
return base.list();

Это дает мне список объектов Code, ограниченный, как я и ожидал.Однако он также выполняет дополнительные запросы для построения всех неиспользуемых отношений объекта Gift, даже если у меня все сопоставления настроены с режимом выборки Lazy.Это приводит к 4 дополнительным отдельным запросам для каждого из моих результатов 10000+.

У меня есть код для выполнения запроса с использованием HQL, который работает, как и ожидалось:

String hql = "select c FROM Code c inner join c.gift g inner join g.giftVendors gv inner join gv.giftVendorStatus gvs" +
    " WHERE gvs.description like :desc";
HashMap<String,Object> params = new HashMap<String, Object>();
params.put("desc", "Online%");
return performQuery(hql, params);

Этот код дает мнеСписок объектов Code, как и ожидалось, без выполнения всех дополнительных запросов для заполнения объекта Gift.Как я могу сказать Hibernate не выполнять эти дополнительные запросы с помощью API Criteria?

ОБНОВЛЕНИЕ: Проблема здесь не в получении таблицы подарков, а в не связанных отношениях один-к-одному из таблицы подарков.Например, Gift имеет непосредственное отношение к GiftCommentAggregateCache.Эта таблица никоим образом не связана с этим конкретным запросом, поэтому я ожидаю, что будут применены ленивые правила инициализации, и запрос к GiftCommentAggregateCache не будет выполняться, если не будет предпринята попытка чтения.Однако, с запросом Criteria, написанным, как указано выше, он создает отдельный запрос для заполнения объекта модели для GiftCommentAggregateCache.

Если я использую:

base.setFetchMode("gift.giftCommentAggregateCache", FetchMode.JOIN);

, то у меня нет проблем,Однако это означает, что для того, чтобы это работало так, как я ожидал, мне нужно добавить эту строку для каждого неиспользованного отношения один к одному, которое имеет Дар.Есть идеи, почему ленивые правила, указанные в сопоставлениях, здесь не вступают в игру?

Есть несколько разных вещей, которые я пробовал:

base.setFetchMode("gift", FetchMode.LAZY); // Still does additional queries

и

base.setFetchMode("gift", FetchMode.SELECT); // Still does additional queries

и

base.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); // Still does additional queries

и

base.setResultTransformer(Criteria.ROOT_ENTITY); // Still does additional queries

и

base.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP); // Still does additional queries

и

base.setProjection(Projections.property("gift")); // Does not do additional queries, but incorrectly returns a List of Gift objects, instead of a List of Code objects

1 Ответ

0 голосов
/ 25 февраля 2011

Из документации Hibernate :

Соединение выборки: Hibernate извлекает связанный экземпляр или коллекцию в том же SELECT, используя OUTER JOIN.

Другими словами, попробуйте использовать base.setFetchMode («подарок», FetchMode.JOIN)

Надеюсь, это поможет.

Приветствия

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