2013-08-21 21 views
0

我有JPA2 /休眠问题4.2/MySQL的5.1 /爪哇6JPA和JPQL MEMBER总是返回空结果

我有下面的类,用户,它具有一个属性,Set<Role>,其中角色是一个枚举。这里是类:

@Entity 
public class User 
{ 
    private static final long serialVersionUID = 1L; 

    @ElementCollection(fetch=FetchType.EAGER) 
    @Enumerated(value=EnumType.STRING) 
    protected Set<Role> roles; 

    // .. other stuff 
} 

public enum Role { ADMIN, OPERATOR, ... } 

我试图创造既CriteriaQuery中,为此JPQL查询,但由于某种原因,两者每次返回一个空列表,即使角色存在。

这里是我的标准查询代码:

CriteriaBuilder builder = getEntityManager().getCriteriaBuilder(); 
CriteriaQuery<User> query = builder.createQuery(User.class); 
Root<User> root = query.from(User.class); 

query.where(builder.isMember(Role.ADMIN, root.<Set<Role>>get("roles"))); 

List<User> result = getEntityManager().createQuery(query).getResultList(); 

这里是我创建JPQL:

String jpql = "SELECT * FROM com.mypackage.user.User WHERE (:roles1 MEMBER OF roles))"; 
Query query = em.createQuery(jpql); 
query.setParameter("roles1", Role.ADMIN); 
List result = em.getResultList(); 

users表中包含了所有角色的单个用户,但是这些都正在返回任何结果。我需要为我正在做的工作同时拥有JPA和JPQL版本。请帮忙!

+0

什么是生成的SQL?当你直接执行这个生成的SQL时会发生什么? –

+0

我已经改变了jpql,所以它现在做了一个计数 - 休眠本机SQL提供:'从用户user0_中选择count(*)作为col_0_0_在哪里? in(从User_roles roles1_选择roles1_.roles,其中user0_.id = roles1_.User_id)' - 如果我更改了?到'管理员'它的作品。 – fancyplants

+1

SQL看起来正确。尝试查看哪些值实际上与语句绑定,在数据库上自己执行查询,检查数据并检查您是否连接到正确的数据库。 –

回答

1

好的,对于那些有类似问题的人,我有a解决方案,但它不是很好。感谢JB Nizet提供的指针,帮助他们诊断问题。

问题是因为在处理不是字符串的数据时,JPA和/或Hibernate的限制。在这里,我使用了一个枚举,它在角色对象和它在数据库中的字符串表示之间进行相等性测试,而不是将我传入的角色转换为它的数据库表示(如您所期望的那样),然后做比较。

要获得JPQL版本去,我所做的:

String jpql = "SELECT * FROM com.mypackage.user.User WHERE (:roles1 MEMBER OF roles))"; 
Query query = em.createQuery(jpql); 
query.setParameter("roles1", Role.ADMIN.toString()); 
List result = em.getResultList(); 

要解决的JPA的版本,我所做的:

CriteriaBuilder builder = getEntityManager().getCriteriaBuilder(); 
CriteriaQuery<User> query = builder.createQuery(User.class); 
Root<User> root = query.from(User.class); 

query.where(builder.isMember(Role.ADMIN.toString(), root.<Set<String>>get("roles"))); 

List<User> result = getEntityManager().createQuery(query).getResultList(); 

如果任何人都可以纠正这个代码,并使它这样了toString是不必要的(我没有排除我只是没有正确设置它的想法),如果你能把我说得对,我会很感激。 :)