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

2022-09-03 03:43:13

我正在编写一个基于类别集合的查询的JPQL查询。我的类别可以为空,因此我正在使用: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: Operand 应包含 1 列

而休眠相关跟踪是

category6_.category_id in ( ? , ? ) or ( ? , ? ) 是 null )

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

谢谢。


答案 1

我能够像这样得到它:

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

答案 2

所以我被困在做一些非常相似的事情上。基本上,您要检查是否

  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)) "

不是世界上最好的解决方案,但它是功能性的。


推荐