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

Hop*_*ing 5 java mysql hibernate jpa jpql

我正在写一个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);
Run Code Online (Sandbox Code Playgroud)

当类别为NULL时,以上方法可以正常工作。但是,当类别超过一个值时,我得到了错误

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

与休眠有关的痕迹是

(?,?)或(?,?)中的category6_.category_id为null)

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

谢谢。

小智 9

我能够这样得到:

coalesce(:myIdCollection, null) is null or id in (:myIdCollection)
Run Code Online (Sandbox Code Playgroud)

  • 您甚至不需要在`coalesce`函数中硬编码`null`值:`coalesce(:myIdCollection) is null or id in (:myIdCollection)`应该可以完成这项工作。 (2认同)

Loa*_*ian 5

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

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

问题是没有很好的方法来处理这部分:

:categories = NULL
Run Code Online (Sandbox Code Playgroud)

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

@p0, @p1 = NULL
Run Code Online (Sandbox Code Playgroud)

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

(@p0, @p1) = NULL
Run Code Online (Sandbox Code Playgroud)

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

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

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

String catString = "";
if (categoryList != null && !categoryList.isEmpty()) catString = "HasCats";
Run Code Online (Sandbox Code Playgroud)

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

WHERE (:catsString = '' or cats IN (:categories)) "
Run Code Online (Sandbox Code Playgroud)

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


小智 5

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

(cats in :categories or (:categories) IS NULL)
Run Code Online (Sandbox Code Playgroud)