【问题标题】:JPA Query: List of enums IN list of enumsJPA 查询:枚举列表 IN 枚举列表
【发布时间】:2017-11-15 16:54:09
【问题描述】:

我有一个包含枚举列表的搜索条件对象。

搜索结果还有一个枚举列表。

我希望能够找到包含搜索条件中列出的所有枚举的搜索结果。

我尝试了以下方法,但得到了一个

IllegalArugmentException 参数值 [ENUM_VALUE_X] 做了 与预期类型不匹配 java.util.Collection (n/a)

我觉得我在某个地方犯了一个愚蠢的错误,但无法弄清楚它是什么。我做错了什么?

String queryStr = "select distinct result from SearchResult result where 
result.enumsList IN :enumsList"
...
Query query = entityManager.createQuery(queryStr, SearchResult.class);
query.setParameter("enumsList", criteria.getEnumsList());
//criteria.getEnumsList() = [ENUM_VALUE_X, ENUM_VALUE_Y]

【问题讨论】:

  • 因为 IN 运算符用于单个值 IN 多个值,所以它显然是无效的语法。任何 JPA 文档都会告诉你这一点
  • 请向我们展示 SearchResult 实体。
  • @BillyFrost 我就是这么想的。但是如果不单独检查列表中的每个元素,就没有办法检查列表IN列表吗?
  • @wypieprz 这是一个巨大的文件。有什么你想看的特定部分/原因吗?
  • 我猜有像 Collection<EnumValue> enumsList 这样的东西,正如 Billy Frost 所提到的,JPQL 将无法工作。一种解决方法是构建一个动态查询,其中一个接一个地添加元素,或者重新设计实体模型(例如 MapIN 表达式一起使用,因此使用这样的映射,其中 K 充当枚举type 和 V 充当它的描述就可以了)。

标签: java jpa enums


【解决方案1】:

这是解决这个问题的一种相当丑陋的方法(尽管它 100% 有效):

List<SomeEnum> enumList = criteria.getEnumsList();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < enumList.size(); i++) {
    if (i == 0) {
        sb.append("WHERE :e").append(i).append(" MEMBER OF result.enumsList");
    } else {
        sb.append(" AND ").append(":e").append(i).append(" MEMBER OF result.enumsList");
    }
}
Query query = em.createQuery("SELECT DISTINCT result FROM SearchResult result "+ sb.toString(), SearchResult.class);
for (int i = 0; i < enumList.size(); i++) {
    query.setParameter("e" + i, enumList.get(i));
}
List<SearchResult> resultList = query.getResultList();

这是zyexal 的建议,虽然它匹配一个出现并检查列表的长度,但它也可以正常工作。所以分隔符的例外是可能的:

Query query = em.createQuery("SELECT DISTINCT result FROM SearchResult result JOIN result.enumsList e WHERE e IN :enums GROUP BY result HAVING COUNT(distinct e) = :enumsSize", SearchResult.class);
query.setParameter("enums", criteria.getEnumsList());
query.setParameter("enumsSize", criteria.getEnumsList().size());
List<SearchResult> resultList = query.getResultList();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多