【问题标题】:HQL: How to filter for property if it is null at timesHQL:如果有时为空,如何过滤属性
【发布时间】:2012-08-21 15:18:13
【问题描述】:

两个域类(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。

谢谢

【问题讨论】:

  • stackoverflow.com/questions/2093025/… 显示了一些关于如何禁用多态查询行为的选项(希望这将消除a.class in ('someChildOfA', 'anotherChildOfA', 'aThirdChildOfA') 语句)关于如何在每个查询的基础上执行此操作还有一个粗略的想法,我需要。有人在 Grails 中做过类似的事情吗?

标签: hibernate grails join hql isnull


【解决方案1】:

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

我遇到了同样的问题,在 HQL 中解决它的唯一方法是检查 null 前任: 替换你的 where 如下

where (a.id is null OR dateCreated &lt; someDate)

我不明白选课问题。这行得通

【讨论】:

  • 这肯定是一个更好的答案。
  • 嗯,你的建议正是我上面所做的。我的问题是这是一个多态查询,即 Hibernate 将where a.class in ('someChildOfA', 'anotherChildOfA', 'aThirdChildOfA') 插入到查询字符串中,所以它看起来像where (a.id is null OR dateCreated &lt; someDate) and a.class in ('someChildOfA', 'anotherChildOfA', 'aThirdChildOfA'),如果 a 为空,它仍然会导致问题,因为括号仍然不行。
【解决方案2】:

您不能从A 中选择孤立的Bs(其中anull)——这毫无意义。为此,您需要从 B 中选择不同的查询。

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

【讨论】:

  • 为什么你认为它没有意义?也许我的描述有点不清楚。例如:考虑 A 的产品项目购买和 B 的购买者。购买链接到其购买者。要了解每个买家的购买情况并包括没有任何购买的买家,这对我来说很有意义......
  • HQL UNION 替换是个好主意,但最后,我需要从加入的 A - B 结果集中进行选择(因为对 A 和 B 的属性有一些分组和排序步骤),这似乎总是包含一个 where a.class in ('someChildOfA', 'anotherChildOfA', 'aThirdChildOfA') 子句,它删除所有 a 为空的元组 - 似乎不可能阻止这种情况。也许可以告诉hibernate不要包含这个类选择语句?
  • 1) 在我看来,就您的示例而言,您正在选择购买 - 抱歉,我弄错了,您正在为两个表构建摘要。
猜你喜欢
  • 2017-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多