Итак, у меня довольно сложный запрос, который я пытаюсь сделать с использованием 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