HQL查询中不需要的隐式内部联接

时间:2019-03-16 02:20:32

标签: sql hibernate hql querydsl

我正在尝试编写QueryDSL表达式以选择列值。距“ from”表有几处联接:

a.b.c.get(0).field

其中b可以是空对象,但如果不是,则c集合中最多有1条记录。 我想要的是

new CaseBuilder()
 .when(a.b.isNotNull().and(a.b.c.isNotEmpty()))
 .then(a.b.c.get(0).field.stringValue())
 .otherwise(Expressions.stringTemplate("''"))

这会隐式生成SQL中的bc表的内部联接,这不是我想要的,因为当b实际上是null时,它不返回任何结果。无论如何,添加显式左外部联接都不会停止隐式联接。我很确定我没有考虑正确的方法,请帮助我摆脱困境:-)

1 个答案:

答案 0 :(得分:1)

当我添加support for implicit joins to jOOQ时,我已经研究了该主题,并偶然在Hibernate中发现了这种“局限性” /设计。我最近已将此问题报告给Hibernate-dev邮件列表,因为我明确认为这是一个错误: http://lists.jboss.org/pipermail/hibernate-dev/2018-February/017299.html

我不明白为什么任何投影表达式都应该“无意间”在FROM子句上产生一个过滤器。这似乎与人们根据关系代数思考时可能建立的直觉相反。

您可以阅读对该电子邮件的回复,特别是Steve Ebersole的基本原理:

  

我是说我不能再看   HQL / JPQL,并告诉它将使用哪种SQL连接   取决于映射的关联。前面提到过这种方法   在线程中。但是您澄清了您的意思是隐式联接应该   总是被解释为外部联接。

     

您可以插入自己的查询处理并解释隐式联接   随你怎么便。不过,这并不是当前最琐碎的任务。

我认为在Hibernate中不会很快解决此问题。因此,这里的解决方法是显式构建所有外部联接,并且每当您希望它们产生外部联接时都不使用任何隐式联接。