我有一个实体'Parent',它有一组枚举
private Set<MyEnum> myEnums = EnumSet.noneOf(MyEnum.class);
@CollectionOfElements(targetElement=MyEnum.class)
@JoinTable
(name="PARENT_MY_ENUM",
joinColumns=@JoinColumn(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,则搜索集合ENUM_A,ENUM_B,ENUM_C的搜索应仅返回实体A.搜索ENUM_B和ENUM_C应该不返回任何内容。
我如何在Hibernate中做到这一点? 如果我做
select p from Parent p where p.myEnums IN (:searchCollection) and size(p.myEnums) = size(:searchCollection)
然后这将返回第一次搜索的两个实体。
有什么想法吗?
更新:我通过弄清楚如何在MySQL中执行此操作更进一步,但将此应用于Hibernate会生成无效的SQL。 您可以使用带有EXISTS的子查询,如:
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
)
但是当我尝试在Hibernate中做同样的事情时:
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错误还是我做错了什么?
答案 0 :(得分:0)
我认为你可以在java中做到这一点。执行您最初提出的查询,迭代结果并排除(iterator.remove()
)误报。它应该是O(n)
,我相信MySQL需要相同的时间来过滤你的结果。
答案 1 :(得分: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)