【问题标题】:Is there anyway I can use JPQL's SIZE function for binding parameters in a WHERE clause?无论如何我可以使用 JPQL 的 SIZE 函数在 WHERE 子句中绑定参数吗?
【发布时间】:2022-09-29 22:25:34
【问题描述】:

无论如何我可以使用 JPQL 的SIZE 函数在WHERE 子句中绑定变量吗?

像这样的东西:

and (size(:distributor_ids) = 0 or d.id in (:distributor_ids))

Hibernate 抛出以下异常:

Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Unexpected expression ? found for collection function size

我的查询很大,但是这个 AND 子句相当简单:如果列表为空,则检索所有内容;如果列表不为空,则检索所有满足d.id IN (:distributor_ids) 的行。

有没有办法做到这一点?

    标签: java hibernate jpql


    【解决方案1】:

    如果参数为空或只有 id 与参数匹配的项目,您似乎想要返回所有内容。

    正如它提到的here,目前这是不可能的,尽管您可能对建议的workaround 感兴趣。

    有没有办法做到这一点?

    就我个人而言,我会在服务类中的 Java 端调用 SomeRepository.findAll() 为空集合,而 SomeRepository.findAllByIds() 则相反。

    【讨论】:

    • 也许我把它说得太简单了。我的查询确实很大,但是这个 AND 子句非常简单。
    • @MatheusCirillo 如果您的查询中的d 是连接实体的别名,那么我回答中第二个链接中的解决方法可能对您有用。
    • 我感谢您的帮助!当我使用 Spring JPA Repositories 时,我提供了使用 SpeL 的解决方案:and (:#{#distributor_ids == null} = true or d.id in (:distributor_ids))。像魅力一样工作。
    • 好的!或者,这可以使用*RepositoryImpl 类来实现
    • 顺便说一句,我认为你应该分享你的解决方案作为这个问题的答案,因为很多人都面临着类似的问题
    【解决方案2】:

    是的,这很简单。如果列表不为空,则仅将条件添加到您的查询中。使用 JPA 标准,您可以执行以下操作:

    List<Integer> distributorIds = ...
    if (!distributorIds.isEmpty()) {
        criteriaQuery.where(root.get("id").in(distributorIds));
    }
    

    在更大的查询中,您可以在列表中收集单个 Predicate 对象,最后设置它们的连词,通过 CriteriaBuilder.and() 创建作为 where 子句谓词。

    【讨论】:

      猜你喜欢
      • 2016-03-30
      • 2011-11-29
      • 2013-12-26
      • 2017-07-18
      • 2017-05-07
      • 2018-02-26
      • 2013-06-20
      • 1970-01-01
      • 2017-01-04
      相关资源
      最近更新 更多