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

时间:2017-07-18 10:35:49

标签: java mysql hibernate jpa jpql

我正在编写一个基于 Categories 集合查询的JPQL查询。我的类别可以为null,因此我正在检查使用: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);

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

  

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

hibernate相关的跟踪是

  

category6_.category_id in(                   ? ,?               )               要么 (                   ? ,?               ) 一片空白           )

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

感谢。

4 个答案:

答案 0 :(得分:3)

我能够这样得到:

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

答案 1 :(得分:1)

所以我被困在做类似的事情。基本上,您要检查是否有一个

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

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

答案 2 :(得分:1)

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

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

答案 3 :(得分:0)

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返回一个空集合。

哦,我修复了你的查询(虽然我没有测试它)。