
[英]Passing list to WHERE IN clause with JPQL causes IllegalArgumentException
[英]String list identity in where clause of JPA / JPQL Query
说我有一个@Entity
喜欢
class C {
List<String> sequence;
}
我想查询与给定列表完全匹配的C
实例。 (我知道这是顺序敏感的,我可以接受。)我正在使用EclipseLink并通过JPQL查询。
我尝试了明显的方法:
List<String> querySeq = ... // some list to be used in the where clause
em.createQuery("select c from C c where c.sequence = :qs", C.class)
.setParameter("qs", querySeq);
当我尝试使用getResultList()
执行查询时,此操作将失败。 错误是java.sql.SQLSyntaxErrorException: row column count mismatch
。
我也尝试了join
:
select c from C c join c.sequence s where s in :qs
但这也失败了,说The collection-valued path 'c.sequence' must resolve to an association field.
我对此的解释是, join
对原始元素的集合不起作用,而仅对关系起作用。
所以我的问题是:
什么是正确的方法?
另外,是否有一种方法可以对基本集合进行更复杂的操作,例如查询(设置)交集,并集或差异?
经过对互联网和JPA规范的研究,我发现我们无法使用JPQL比较两个列表。
我建议选择整个列表,然后使用Apache Commons CollectionUtils将其与第二个列表进行比较。 它提供了相交和相减的功能。
我找不到任何可以使用JPQL直接比较列表的解决方案或文章。 但是,您可以使用一种机制来测试值是否为集合的成员 。
这个过程并不优雅,但是经过一些调整,我们可以构建一个与此类似的查询(无法测试代码,但是我认为它描述了这个想法,并且在逻辑上应该可行):
String query = "SELECT c FROM C c";
String checkValue = "";
for(int i = 0; i<queryString.size();i++){
checkValue = queryString.get(i);
if(i==queryString.size()-1){
query += " WHERE '" + checkValue + "'" + " MEMBER OF c.sequence";
}else{
query += " WHERE '" + checkValue + "'" + " MEMBER OF c.sequence AND";
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.