1

ユーザーは多くの役割を果たすことができます。パラメータ リストから少なくとも 1 つのロールを持つすべてのユーザーを取得したいと考えています。

データ定義は次のようになります。

@Entity
public class User implements Serializable {
    @Id
    @Column(name = "Id",
            nullable = false)
    private long id;

    @Column(name = "LoginName",
            length = 30,
            unique = true,
            nullable = false)
    private String loginName;

    @ElementCollection
    @Enumerated(EnumType.STRING)
    @CollectionTable(name = "Role",
                     joinColumns = @JoinColumn(name = "Id"),
                     uniqueConstraints = @UniqueConstraint(columnNames = {"Id", "Role"}))
    @Column(name = "Role")
    private Set<RoleType> roles = new HashSet<RoleType>();
}


public enum RoleType {
    GUEST,
    ACCOUNTING,
    ADMIN,
    OPERATOR;
}

ここで、パラメーター リストから少なくとも 1 つのロールを持つすべてのユーザーが必要です。リストは動的である場合があります。次のコードを試しました:

String sql = "SELECT DISTINCT u FROM User u JOIN u.roles AS r WHERE r IN :filteredRoles";
Query query = entityManager.createQuery(sql);
List<RoleType> filteredRoles = new ArrayList<RoleType>();
filteredRoles.add(RoleType.ADMIN);
filteredRoles.add(RoleType.ACCOUNTING);
query.setParameter("filteredRoles", filteredRoles);
List<User> result = (List<User>) query.getResultList();

次の例外を受け取ります。

Exception [EclipseLink-6078] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.QueryException
Exception Description: The class of the argument for the object comparison is incorrect. 
Expression: [null] 
Mapping: [org.eclipse.persistence.mappings.DirectCollectionMapping[roles]] 
Argument: [[ADMIN, ACCOUNTING]]
Query: ReadAllQuery(referenceClass=User sql="SELECT DISTINCT t0.Id FROM User t0, Role t1 WHERE ((t1.Role IN ?) AND (t1.Id = t0.Id))")

JPQL のいくつかのバリエーションを試しましたが、成功しませんでした。役立つヒントが得られることを願っています。

4

2 に答える 2

0

2.4 リリースをお試しいただけますか。これは修正済みのようです。

于 2012-09-24T13:50:44.290 に答える
-1

よくわかりませんが、最高の解決策になります。お役に立てば幸いです。

public enum Role {
    AAA, BBB, CCC, DDD;
}

@Entity
public class Student implements Serializable {
    @Id
    private String id;
    private String name;
    @ElementCollection
    @Enumerated(EnumType.STRING)
    @CollectionTable(name = "Role", joinColumns = @JoinColumn(name = "Id"),
                     uniqueConstraints = @UniqueConstraint(columnNames = { "Id", "Role" }))
    @Column(name = "Role")
    private List<Role> roleList;

    public Student() {
    }

    //gettter and setter
}

/**
    Assume :
    ==================          ================
    Student Table               Role Table
    ==================          ================
    R001    Student 1           R001    AAA
    R002    Student 2           R002    BBB
    R003    Student 3           R002    CCC
    R004    Student 4           R004    DDD
                                R001    BBB
                                R002    CCC

*/
public class TestCase {
    public static <T> Set<T> intersection(Set<T> setA, Set<T> setB) {
        Set<T> tmp = new TreeSet<T>();
        for (T x : setA)
          if (setB.contains(x))
            tmp.add(x);
        return tmp;
      }

    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("JPA");
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        Set<Role> paramRoles = new HashSet<Role>();
        paramRoles.add(Role.BBB);
        paramRoles.add(Role.CCC);

        Query q = em.createQuery("SELECT s FROM Student s");
        List<Student> studentList = q.getResultList();
        for (Student s : studentList) {
            Set<Role> result = TestCase.intersection(paramRoles, new HashSet<Role>(s.getRoleList()));
            if (!result.isEmpty()) {
                System.out.println(s.getName());
            }
        }
        em.getTransaction().commit();
        em.close();
    }
}

/** Output :

Student 1
Student 2

*/
于 2012-09-24T04:44:57.980 に答える