Eclipselink生成含IS NULL运算符的查询SQL是否正确?
问题分析与结论
首先可以明确:生成的这段SQL是错误的,完全不符合你的查询意图。
为什么SQL会出错?
你的JPQL查询写的是:
select object(o) from RA where o.sc.code = :someCode and o.ec.code is null
这里的问题出在o.ec.code is null这部分:JPA会把这个条件解析成「关联EC表,然后检查关联到的EC实体的code字段是否为null」,所以生成的SQL里才会出现FROM RA t0, EC t1的笛卡尔关联,还加上了t1.CODE IS NULL和t1.CODE = t0.ec的条件。
但EC表的code是主键(作为RA外键的关联目标),主键通常不允许为null;而且如果RA的ec字段本身是null(也就是没有关联任何EC实体),那么t1.CODE = t0.ec等价于t1.CODE = null,SQL中=与null比较永远返回false,最终这个查询会返回空结果,完全达不到你的需求。
正确的做法是什么?
你的真实需求应该是「查询RA中关联的Cc的code等于指定值,并且RA本身没有关联任何EC实体」,对应的JPQL需要把条件改成o.ec is null,而不是o.ec.code is null:
select object(o) from RA where o.sc.code = :someCode and o.ec is null
这样JPA生成的SQL就不会错误关联EC表,而是直接检查RA表的EC外键字段是否为null,正确的SQL大概会是这样:
SELECT t0.ID, t0.RECUPDATETIME, t0.EC, t0.SC FROM RA t0 JOIN CC t1 ON t0.SC = t1.CODE WHERE t1.CODE = ? AND t0.EC IS NULL
额外补充
如果确实需要检查关联的EC实体的code是否为null(虽然主键一般不会允许null),那你的JPQL写法是对的,但此时生成的SQL逻辑没问题,但业务逻辑上不会有符合条件的数据。显然你的需求不是这个,所以改成o.ec is null就可以解决问题了。
内容的提问来源于stack exchange,提问作者eLearner
相关产品推荐
相关产品推荐

