用户可以扮演很多角色。我想从参数列表中获取至少有一个角色的所有用户。
数据定义如下:
@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;
}
现在我希望所有具有至少一个角色的用户都不在参数列表中。该列表可以是动态的。我尝试了以下代码:
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但没有成功。 我希望收到有用的提示。
答案 0 :(得分:0)
你可以尝试2.4版本,这看起来像是修复过的东西。
答案 1 :(得分:-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
*/