输入参数集合包含 null 的 JPQL 查询
Posted
技术标签:
【中文标题】输入参数集合包含 null 的 JPQL 查询【英文标题】:JPQL query with input parameter collection containing null 【发布时间】:2021-11-21 13:15:36 【问题描述】:我需要在以下 JPQL 查询中通过 IN 表达式比较可为空的实体属性:
@NamedQuery(name = "query",
query = "SELECT e FROM MyEntity e WHERE e.status IN :statuses")
现在,我喜欢显示的集合值输入参数 statuses
可以选择包含null
作为元素:
final List<MyEntity> actual = entityManager.createNamedQuery("query", MyEntity.class)
.setParameter("statuses", Arrays.asList(null, 1L))
.getResultList();
但是,对于 Hibernate/Derby,实际结果列表仅包含状态为 1L
而不是 null
的实体。
我在 JPA 2.2 规范中没有找到关于这个案例的任何内容。是我遗漏了什么还是这个供应商特定的?
this question 的答案只能解决我的部分问题。在他们提出的解决方案中,null
比较被硬生化到查询中,无法通过集合值参数进行控制。
【问题讨论】:
这能回答你的问题吗? Checking for NULL on a Collection in JPQL queries? @Yann39 谢谢,我也发现了这个问题。但是,答案只能解决我的部分问题。在他们提出的解决方案中,null 比较被硬生化到查询中,并且无法通过集合值参数进行控制。 【参考方案1】:作为一名 Java 程序员,null = null
产生 true 可能会让人感到惊讶,在 SQL(和 JPQL)中,null = null
本身就是 null
,这是“虚假的”。因此,null in (null)
也会产生 null。
相反,您需要单独处理 null
并使用 IS NULL
检查:e.status IS NULL OR e.status IN :statuses
。
这在 JPA 规范的 4.11 空值中有描述:
具有 NULL 值的比较或算术运算总是产生未知值。 两个 NULL 值不相等,比较会产生一个未知值。
【讨论】:
谢谢,这很有道理。我确实对这里的 ORM 世界有不同的期望,但是 JPQL 不能修改 SQL 的语义。对于我的具体情况,这意味着我需要引入两个相应的 JPQL 查询(一个带有... IS NULL OR ...
,另一个没有)并在 Java 端决定调用哪一个,对吗?
是的,恐怕是这样!以上是关于输入参数集合包含 null 的 JPQL 查询的主要内容,如果未能解决你的问题,请参考以下文章
将 SQL(不是 JPQL)映射到简单 Java 对象的集合?