Подтвердить что ты не робот

Критерии 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");
4b9b3361

Ответ 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;