问题
Hi I'm trying to select records from one table which doesn't have records in connected many-to-many table with specific values.
I will explain on sample tables:
documentation:
id_documentation
irrelevant_data
user:
id_user
irrelevant_data
documentation_user:
id_documentation
id_user
role
What I want to achieve is to select every single documentation which doesn't have user in specific role. Any ideas?
The main problem is that I'm using java's CriteriaBuilder to create query so using subqueries is impossible (I think).
回答1:
You can add restrictions on your left join using: createAlias(java.lang.String, java.lang.String, int, org.hibernate.criterion.Criterion)
method, see API.
Check this answer for an example on how to use the left join with a criteria.
回答2:
Main problem does not exist - Criteria API do have SubQuery. Query itself selects instances of User and uses not in construct to limit results based to subquery. Subquery selects all users that are connected to document with specific role via DocumentationUser.
回答3:
Try something like this (code not tested):
CriteriaQuery<Documentation> cq = cb.createQuery(Documentation.class);
Root<Documentation> u = cq.from(Documentation.class);
Subquery<Integer> sq = cq.subquery(Integer.class);
Root<User> su = sq.from(User.class);
sq.select(su.get("id_user"));
Join<User, DocumentationUser> du = su.join("documentationUserCollection");
sq.where(cb.equals(du.get("role"), "mySpecificRole"));
cq.where(cb.not(cb.in(u.get("id_user")).value(sq)));
See also this useful answer on SO.
来源:https://stackoverflow.com/questions/15056431/select-records-which-doesnt-have-specific-records-in-joined-table