HQL:如果有时属性为null,如何过滤属性

时间:2012-08-21 15:18:13

标签: hibernate grails join hql isnull

两个域类(bean)

A和B,A具有B型属性b( - > A.b) 此外,A是使用单个表的继承层次结构的父级。

我想使用HQL加入这些,并保留结果集中与A无关的所有B。 如果A和B之间存在关联,我只希望其中一些基于A的某些标准。

我的初始查询看起来像这样

SELECT (a.something, b.something)
FROM A as a RIGHT OUTER JOIN a.b
WHERE a.dateCreated < someDate;

此查询的问题:a有时为null,因此WHERE条件解析为false且不返回元组,因此结果集不包含未与A关联的B。

所以我将查询修改为:

SELECT (a.something, b.something)
FROM A as a RIGHT OUTER JOIN a.b
WHERE a is null or (a.dateCreated < someDate);

这在生成的SQL中没有用,似乎无法控制类选择语句的位置,例如

where a.class in ('someChildOfA', 'anotherChildOfA', 'aThirdChildOfA')
插入

;它必须进入括号内,即

where a is null or (a.dateCreated < someDate and a.class in ('someChildOfA', 'anotherChildOfA', aThirdChildOfA'))

但它最终被添加到外面,即

where (a.id is null OR dateCreated < someDate) and a.class in ('someChildOfA', 'anotherChildOfA', 'aThirdChildOfA')

现在,我有点想法......任何(甚至更干净)的建议?如果重要,我正在使用Grails。

由于

2 个答案:

答案 0 :(得分:2)

你基本上在where子句中有一个带有过滤器的右外连接。此外,由于此过滤器用于左侧表(A),因此连接将缩减为内部连接。

我遇到了同样的问题,在HQL中解决问题的唯一方法是检查null 例如: 将您的位置替换为以下

<强> where (a.id is null OR dateCreated < someDate)

我不明白班级选择问题。这工作

答案 1 :(得分:1)

您无法从B(其中Aa)选择孤立的null - 这没有任何意义。您需要一个不同的查询来从B中进行选择。

如此简单且可能最好的工作方法是发出两个不同的查询。如果这是不可接受的,请尝试HQL UNION replacements,或退回到SQL。