2

次のような @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)
4

1 に答える 1

0

クエリが次の場合:

List<Role> roles = session.createQuery("select u.roles from User u left join fetch u.roles where u.id= :idParam").
     setParameter("idParam", param).
     asList();

私が覚えているように、次の基準が機能するはずです。

List<Role> roles = session.
    createCriteria(Role.class).
    add(Restrictions.eq("users.id", param)).
    setFetchMode("users", FethchMode.EAGER).
    list();

それ以外の場合は、非エンティティ構造のクエリを返すため、ResultTransformer が必要になる場合があります。

于 2012-10-03T15:10:02.637 に答える