2013-08-21 22 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是不必要的(我沒有排除我只是沒有正確設置它的想法),如果你能把我說得對,我會很感激。 :)