Reputation: 27455
I got two classes User and Role which are mapped to each other using a many to many associations. Now I'm trying to query all users which doesn't have a certain role using the Hibernate Criteria API. But I'm a little bit stuck.
To query users with a certain role I use the following query, which works just fine.
Session session = getSessionFactory().getCurrentSession();
Criteria mainCrit = session.createCriteria(boClass);
return mainCrit.createAlias("roles", "r").add( Restrictions.eq("r.name", roleName)).list();
Now I'm a little bit confused how to reverse the query and get all user that don't have a certain role. If possible I want to explicit exclude a certain role and don't query for all roles chaining them with OR as there may be more roles added later dynamically.
UPDATE
To get a better understanding of my scenario you can see the association I'm trying to query in another question.
Furthermore I would also add that the name property of the Role class is an Enum, don't know if this is important or changes the way to query the database.
Upvotes: 0
Views: 998
Reputation: 691635
There's perhaps a more elegant way, but the only one I've found is to query for all the users for which there doesn't exist any role in the user's roles which has the given role name.
This is done like this:
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));
It's equivalent to the following HQL query:
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);
Upvotes: 2