【问题标题】:String list identity in where clause of JPA / JPQL QueryJPA / JPQL查询的where子句中的字符串列表标识
【发布时间】:2015-03-24 22:59:31
【问题描述】:

假设我有一个@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 不适用于原语集合,而仅适用于关系。

所以我的问题是:

这样做的正确方法是什么?

另外,有没有办法对原始集合进行更复杂的操作,例如查询(集合)交集、联合或差异?

【问题讨论】:

  • 实体在数据库中是如何表示的?
  • @PradeepPati 不必考虑这个问题是使用 ORM 的主要论据之一吗? ;-)
  • em.createQuery 无法显式映射到实体。你的意思是createNativeQuery?如果是这个意思,那么您的查询应该如下所示:select sequence from C c where c.sequence = :qs。你也不应该使用List&lt;String&gt; sequence,因为你得到的结果是一个实体列表。
  • @pmp 对不起,我不明白你的评论。我使用带有类参数的em.createQuery,它创建了一个TypedQuery&lt;T&gt;,我可以从中接收一个输入的结果列表。我想要c.sequence 与给定序列匹配的Cs 列表(即列表)。
  • 您使用的是 JPA JPQL 还是 Hibernate?

标签: java jakarta-ee jpa eclipselink jpql


【解决方案1】:

我找不到任何可以使用 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";
    }
}

【讨论】:

  • 我很确定每个 MEMBER OF 也是一个子查询。所以不幸的是,这是一个 n+1 的方法
【解决方案2】:

在对互联网和 JPA 规范进行研究后,我发现我们无法使用 JPQL 比较两个列表。

我建议选择整个列表,然后使用 Apache Commons CollectionUtils 将其与第二个列表进行比较。它提供了intersectionsubtraction 的功能。

【讨论】:

  • “选择整个列表”是什么意思?从数据库中检索所有实体正是我想要避免使用查询的原因。
猜你喜欢
  • 1970-01-01
  • 2017-01-22
  • 2015-09-12
  • 2011-02-14
  • 2012-02-02
  • 1970-01-01
  • 1970-01-01
  • 2013-08-24
  • 1970-01-01
相关资源
最近更新 更多