Запрашивает сопоставление «многие ко многим», когда сущность не имеет определенного значения, с помощью Hibernate Criteria API - PullRequest
0 голосов
/ 29 августа 2011

Я получил два класса User и Role, которые сопоставлены друг с другом, используя множество-много ассоциаций. Сейчас я пытаюсь опросить всех пользователей, у которых нет определенной роли, используя Hibernate Criteria API. Но я немного застрял.

Для запроса пользователей с определенной ролью я использую следующий запрос, который прекрасно работает.

Session session = getSessionFactory().getCurrentSession();          
Criteria mainCrit = session.createCriteria(boClass);
return mainCrit.createAlias("roles", "r").add( Restrictions.eq("r.name", roleName)).list();

Теперь я немного запутался, как отменить запрос и получить всех пользователей, у которых нет определенной роли. Если возможно, я хочу явно исключить определенную роль и не запрашивать все роли, объединяя их в цепочку с ИЛИ, поскольку позже может быть динамически добавлено больше ролей.

UPDATE

Чтобы лучше понять мой сценарий, вы можете увидеть связь, которую я пытаюсь задать, в другой вопрос .

Кроме того, я бы также добавил, что свойством name класса Role является Enum, не знаю, важно ли это или изменяет способ запроса базы данных.

1 Ответ

2 голосов
/ 30 августа 2011

Возможно, есть более элегантный способ, но единственный, который я нашел, - это запросить всех пользователей, для которых не существует никакой роли в ролях пользователя с заданным именем роли.

Это делается так:

Criteria c = session.createCriteria(User.class, "user");

DetachedCriteria roleOfUserWithName = DetachedCriteria.forClass(Role.class, "role");
roleOfUserWithName.createAlias("role.users", "userOfTheRole");
roleOfUserWithName.add(Restrictions.eqProperty("userOfTheRole.id", "user.id"));
roleOfUserWithName.add(Restrictions.eq("role.name", roleName);
roleOfUserWithName.setProjection(Projections.id());

c.add(Subqueries.notExists(roleOfUserWithName));

Это эквивалентно следующему HQL-запросу:

select user from User user where not exists (
    select role.id from Role role inner join role.users userOfTheRole
    where userOfTheRole.id = user.id
    and role.name = :roleName);
...