Критерии Hibernate объединяют запросы от одного до многих
У меня есть класс Cat и класс Owner. У кошки есть один владелец, но у владельца может быть много кошек. То, что я хочу спросить, это получить всех владельцев, у которых есть кошка с голубыми глазами.
class Cat {
Owner owner; //referenced from Owner.id
String eyeColor;
}
class Owner {
List<Cat> catList;
}
Я попробовал несколько кодов, но я действительно не знаю, что делать.
Criteria criteria = getCurrentSession().createCriteria(cat.getClass(), "cat");
criteria.createAlias("cat.owner", "owner");
criteria.add(Restrictions.eq("cat.eyeColor", "blue");
Ответы
Ответ 1
Критерии могут отображать только прогнозы или корневой объект. Не какая-то объединенная сущность. Таким образом, некоторые запросы не могут выражаться с помощью критериев (что является еще одной веской причиной использования HQL, в дополнение к гораздо лучшей читаемости и краткости).
Все здесь не потеряно, потому что ваша ассоциация двунаправлена. Таким образом, вам просто нужен эквивалент запроса HQL
select distinct owner from Owner owner
join owner.cats cat
where cat.eyeColor = 'blue'
Что такое
Criteria c = session.createCriteria(Owner.class, "owner");
c.createAlias("owner.cats", "cat");
c.add(Restrictions.eq("cat.eyeColor", "blue");
c.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
Ответ 2
Попробуй это:
DetachedCriteria dc = DetachedCriteria.forClass(Cat.class, "inner")
.add(Restrictions.eq("eyeColor", "blue"))
.add(Restrictions.eqProperty("inner.owner", "outer.id"));
session.createCriteria(Owner.class, "outer")
.add(Subqueries.exists(dc))
.list();
Это может использовать индекс в базе данных и не будет выполнять distinct
операцию в памяти, как в версии @JB Nizet (см. Мой комментарий там). Индекс будет:
CREATE INDEX idx_cat_owner_eyecolor ON Cat(fkOwner, eyeColor)
Думайте о distinct
операции (в SQL или в памяти) как о запахе кода. Он редко используется, и многие начинающие программисты используют его, чтобы решить проблему "почему у меня есть этот ряд дважды". Это почти всегда можно переписать, например, в этом случае. Случаев использования, когда это необходимо, мало.
Ответ 3
Может ли кто-нибудь дать решение, используя критерии и отдельные критерии, используя подзапросы.
Мой запрос: Выберите * из формы объединения версий в Version.xsdVersionId = Form.xsdVersionId, где Version.versionId = 25;