在 JPQL 查询中检查集合上的 NULL?

问题描述 投票:0回答:5

我正在编写一个 JPQL 查询,该查询基于 Categories 集合进行查询。我的类别可以为空,因此我正在使用 :categories=NULL 进行检查。

@Query("Select v from Vendor v join v.org vorg join v.categories cats WHERE vorg.email =:email AND (cats in :categories or :categories = NULL)")
Set<Vendor> filterVendors(@Param("emailId") String emailId, @Param("categories") Set<Category> categories);

当类别为 NULL 时,上述工作正常。但是,当类别超过一个值时,我会收到错误

java.sql.SQLException:操作数应包含 1 列

与休眠相关的跟踪是

category6_.category_id 在 ( ? , ? ) 或者 ( ? , ? ) 一片空白 )

如何在 JPQL 中检查集合上的 null ?我认为解决这个问题应该可以解决这个错误。任何帮助表示赞赏

谢谢。

java mysql hibernate jpa jpql
5个回答
41
投票

我能够像这样得到它:

coalesce(:myIdCollection, null) is null or id in (:myIdCollection)

6
投票

所以我一直在做类似的事情。基本上你想检查一下是否

  1. 您传入的集合为空:则不要将其包含在查询中
  2. 您传入的集合已填充:然后将其包含在查询中

问题在于没有好的方法来处理这部分:

:categories = NULL

这是因为当翻译成 SQL 时,它会看起来像这样(当集合中有 2 个项目时):

@p0, @p1 = NULL

您也不能将其括在括号中,因为这在 SQL 中无效:

(@p0, @p1) = NULL

我尝试使用合并将值减少到 NULL,但我也无法让它工作。

基本上据我所知,JPQL 中没有任何东西可以让您运行某种集合函数(哈希集等)来查看它是否已填充。如果有人知道,请告诉我们。

最后我求助于黑客,在调用代码中我检查集合以查看它是否已填充。如果不是,我简单地再传递一个参数......一个空字符串。

String catString = "";
if (categoryList != null && !categoryList.isEmpty()) catString = "HasCats";

然后在 JPQL 中执行以下操作:

WHERE (:catsString = '' or cats IN (:categories)) "

不是世界上最好的解决方案,但它很实用。


4
投票

如果任何使用 PostgreSQL 的人遇到这个问题,可以通过添加括号轻松修复:

(cats in :categories or (:categories) IS NULL)

1
投票
Select v from Vendor v join v.categories cats WHERE vorg.email =:email AND (cats in :categories or cats IS EMPTY)

您可以使用

IS [NOT] EMPTY
运算符来测试空集合。 JPA 不一定会返回 NULL 集合。想想看,DB 返回的是一个空集合。

哦,我解决了你的问题(虽然我没有测试它)。


0
投票

使用 spring-data,您可以在 @Query 定义上使用 SpEL

例如:

其中 (:#{#categoryIds == null || #categoryIds.isEmpty()} = true 或 s.id in (:categoryIds))

几种情况下生成的where条件是:

  1. 空类别ID

其中 (?=1 或 1=0)

  1. 空类别ID

其中 (?=1 或 s3_0.SHOP_CATEGORY_ID in(?))

  1. categoryIds 中有两个项目

其中 (?=1 或 s3_0.SHOP_CATEGORY_ID in(?,?))

  1. categoryId 中的一项

其中 (?=1 或 s3_0.SHOP_CATEGORY_ID in(?))

© www.soinside.com 2019 - 2024. All rights reserved.