次のような @ManyToMany 関係に 2 つのエンティティがあります。
@Entity @Table(name = "USERS") public class User implements EntityMetaModel, Serializable { @Id @GeneratedValue(strategy = IDENTITY) @Column(name = "ID", unique = true, nullable = false) private Integer id; @Column(name = "USERNAME", unique = true, length = 20) private String username; @Column(name = "PASSWORD", nullable = false, length = 32) private String password; @Column(name = "ENABLED") private Boolean enabled; @ManyToMany( cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = (FetchType.LAZY) ) @JoinTable( name = "USER_ROLES", joinColumns = @JoinColumn(name="USERID", referencedColumnName="ID"), inverseJoinColumns = @JoinColumn(name="ROLEID", referencedColumnName="ID") ) @SequenceGenerator( name = "sgIdUserRoles", sequenceName = "SQ_ID_USER_ROLES" ) @CollectionId( columns = {@Column(name="ID")}, type = @Type(type="integer"), generator = "sgIdUserRoles" ) @Fetch(value = FetchMode.SELECT) private Collection<Role> roles = new HashSet<Role>(); } @Entity @Table(name = "ROLES") public class Role implements EntityMetaModel, Serializable { @Id @GeneratedValue(strategy = IDENTITY) @Column(name = "ID", unique = true, nullable = false) private Integer id; @Column(name = "ROLENAME", unique = true, length = 50) private String rolename; @ManyToMany( cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = (FetchType.LAZY) ) @JoinTable( name = "USER_ROLES", joinColumns = @JoinColumn(name="ROLEID", referencedColumnName="ID"), inverseJoinColumns = @JoinColumn(name="USERID", referencedColumnName="ID") ) @SequenceGenerator( name = "sgIdUserRoles", sequenceName = "SQ_ID_USER_ROLES" ) @CollectionId( columns = {@Column(name="ID")}, type = @Type(type="integer"), generator = "sgIdUserRoles" ) @Fetch(value = FetchMode.SELECT) private Collection<User> users = new HashSet<User>(); }
私はメタモデルを作成しました:
@StaticMetamodel(User.class) public class User_ { public static volatile SingularAttribute<User, Integer> id; public static volatile SingularAttribute<User, String> username; public static volatile SingularAttribute<User, String> password; public static volatile SingularAttribute<User, Boolean> enabled; public static volatile CollectionAttribute<User, Role> roles; } @StaticMetamodel(Role.class) public class Role_ { public static volatile SingularAttribute<Role, Integer> id; public static volatile SingularAttribute<Role, String> rolename; public static volatile CollectionAttribute<Role, User> users; }
クラス User は Role の Collection を持っています。JPA2 CriteriaQuery から行う必要があるのは、ID で指定されたユーザーを持たないロールを見つけることです。このような CriteriaQuery を実行するにはどうすればよいですか?
select r.id, r.rolename
from roles r
where not exists
(select 1
from user_roles ur
where ur.roleid = r.id
and ur.userid = :userid)