2011-07-06 60 views
5

枚舉比較兩個集合我有有一組枚舉與Hibernate和SQL

private Set<MyEnum> myEnums = EnumSet.noneOf(MyEnum.class); 

    @CollectionOfElements(targetElement=MyEnum.class) 
    @JoinTable 
     (name="PARENT_MY_ENUM", 
     [email protected](name="PARENT_ID")) 
    @Enumerated(EnumType.STRING) 
    @Column (name="MY_ENUM", nullable=false) 
    public Set<MyEnum> getMyEnums(){ 
     return myEnums; 
    } 


public MyEnum { 
ENUM_A, 
ENUM_B, 
ENUM_C, 
ENUM_D; 
} 

現在我想搜索與MyEnums集合這個實體的實體「父」。只有在搜索集合中設置了所有枚舉的實體才應返回。因此,如果實體A具有ENUM_A,ENUM_B和ENUM_C並且實體B具有ENUM_B,ENUM_C和ENUM_D,則搜索collectoin ENUM_A,ENUM_B和ENUM_C的搜索應當僅返回實體A.搜索ENUM_B和ENUM_C將不返回任何內容。

我將如何做到這一點在休眠? 如果我做

select p from Parent p where p.myEnums IN (:searchCollection) and size(p.myEnums) = size(:searchCollection) 

那麼這將返回兩個實體的優先搜索。

任何想法?

更新:通過計算如何在MySQL中執行此操作,但將其應用於Hibernate會生成無效的SQL,我又進一步了。 你可以使用子查詢與存在什麼樣子:

WHERE EXISTS(
    SELECT pa.PARENT_ID, count(pme.MY_ENUM) FROM PARENT pa, PARENT_MY_ENUM pme 
    where pa.PARENT_ID = pme.PARENT_ID 
    AND pme.MY_ENUM IN ('ENUM_A','ENUM_B') 
    GROUP BY pa.PARENT_ID HAVING count(pme.MY_ENUM) = 2 
) 

但是當我嘗試做同樣處於休眠:

select pa.ParentId, count(pa.myEnums) from Parent pa 
WHERE pa.myEnums IN ('ENUM_A','ENUM_B') 
GROUP BY pa.ParentId HAVING count(pa.myEnums) = 2 

的Hiberante創建該SQL語句:

select pa.CONTAINER_RELEASE_REFERENCE_ID as col_0_0_, count(.) as col_1_0_ from PARENT pa, PARENT_MY_ENUM enum1, PARENT_MY_ENUM enum2, PARENT_MY_ENUM enum3 
where pa.PARENT_ID=enum1.PARENT_ID and pa.PARENT_ID=enum2.PARENT_ID and pa.PARENT_ID=enum3.PARENT_ID 
and (. in ('ENUM_A' , 'ENUM_B')) 
group by pa.PARENT_ID having count(.)=2 

MySQL抱怨'。',來自哪裏以及爲什麼Hibernate使用3個連接到PARENT_MY_ENUM?

這是一個Hibernate的bug或我做錯了什麼?

回答

0

給下面的一個嘗試爲你存在的子查詢

select pa.ParentId, count(en) from Parent pa join pa.myEnums as en 
WHERE en IN ('ENUM_A','ENUM_B') 
GROUP BY pa.ParentId HAVING count(en) = 2 

否則,我不知道這樣的事情可能不會做的工作

select p from Parent p join p.myEnums em 
where (:results) = elements(em) 

select p from Parent p join p.myEnums em 
where (:results) in elements(em) 
+0

感謝Enum的額外連接做到了這一點。非常感謝 – Ben

0

我認爲你可以在java中做到這一點。執行最初提出的查詢,迭代結果並排除錯誤肯定(iterator.remove())。它應該是O(n),我相信MySQL需要相同的時間來篩選結果。

+0

這可能是在問題順序方面相同,但是您還需要考慮da之間傳輸的數據量tabase和應用程序服務器(它們可能或可能不在同一臺服務器上)。可以說只有結果集的百分之一實際上符合標準。因此,讓我們說爲了節省應用程序服務器和數據庫之間的帶寬(和時間),您將最大結果設置爲100,最終只有一行。所以雖然這可能是一項解決方案,但並不能真正解決問題。 – Ben