Java 在JPQL中处理空参数

Java 在JPQL中处理空参数,java,hibernate,jpa,jpql,Java,Hibernate,Jpa,Jpql,我刚刚意识到,当任何参数为null时,JPQL where子句都不能像我预期的那样工作。 例如,这个简单的JPQL查询 SELECT en FROM Entity en WHERE en.name = :name 当name参数为null时,即使数据库中存在名称设置为null的实体,也不会返回任何结果 在这种情况下,Hibernate使用执行SQL,其中entity.NAME=null。显然,这不是由数据库处理的,因为标准定义的为空,而非空比较的(请参阅)。JPQL的运算符也是NULL运算符(

我刚刚意识到,当任何参数为null时,JPQL where子句都不能像我预期的那样工作。 例如,这个简单的JPQL查询

SELECT en FROM Entity en WHERE en.name = :name
name
参数为null时,即使数据库中存在名称设置为null的实体,也不会返回任何结果

在这种情况下,Hibernate使用
执行SQL,其中entity.NAME=null
。显然,这不是由数据库处理的,因为标准定义的
为空,而非空比较的
(请参阅)。JPQL的
运算符也是NULL
运算符(),其行为与SQL()中的行为完全相同

我认为这是一个常见的情况,但快速搜索并没有给我任何有趣的结果

那么,有没有办法在查询中包含空值? 到目前为止,我得出了以下结论:

SELECT en FROM Entity en WHERE (:name IS NULL AND en.name IS NULL) OR en.name = :name
它工作得很好,但看起来并不优雅,尤其是在较大的查询中


另外一个问题:为什么JPQL会模仿SQL的这个奇怪的方面?

不是所有的JPA实现都会将
en.name=:name
name
参数转换为
null
entity.name=null
。例如,我使用的实现(DataNucleus JPA)将其转换为
entity.NAME为NULL
IIRC


JPQL不告诉实现要执行什么SQL,只告诉用户可以定义什么。其余的由实施决定。用户可以决定使用哪个实现。

这与oracle使用is null而不是=null的原因相同。在没有ORM框架的情况下也同样适用。让我们使用一个SQL语句,如-
SELECT*fromtable\u name,其中column\u name=:name
。如果绑定命名参数的值为
null
,则语句不会神奇地改变以自动反映
is null
条件。不是吗?只是这是JPQL而不是SQL,所以实现完全能够相应地决定其SQL,并且应该能够应对。您的解决方案仍然是一个很好的答案谢谢您的回答。不幸的是,我不能简单地将Hibernate更改为其他JPA实现。此外,在我的选项中,DataNucleus不完全符合JPA标准。声明“两个空值不相等。比较两个空值会产生一个未知值。”根据我的记忆,当空参数是一个选项时,他们用于“IS NULL”的自动转换,如果人们愿意,可以直接使用参数文本。因此,法规遵从性不是一个问题(也不是在我的所有使用中)。此外,它们还支持“其他”数据存储,一些SQL92约定在这些数据存储中没有意义,但“isnull”却有意义。