JPA / JPQL 查询的 where 子句中的字符串列表标识

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 比较两个列表。

我建议 select 整个列表,然后使用 Apache Commons CollectionUtils. It offers the functionality of intersection and subtraction 将其与第二个列表进行比较 CollectionUtils. It offers the functionality of intersection and subtraction

我找不到任何可以使用 JPQL 直接比较列表的解决方案或文章。但是有一种机制可以测试一个值是否是 MEMBER OF 集合。

这个过程并不优雅,但通过一些调整,我们可以构建一个类似于此的查询(无法测试代码,但我认为它描述了这个想法和 逻辑上应该可行):

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";
    }
}