Java 在JPQL中处理空参数
我刚刚意识到,当任何参数为null时,JPQL where子句都不能像我预期的那样工作。 例如,这个简单的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运算符(
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”却有意义。