【问题标题】:HQL implicit join in where clause generate cross join instead of inner joinwhere 子句中的 HQL 隐式连接生成交叉连接而不是内部连接
【发布时间】:2013-12-13 00:08:19
【问题描述】:

我正在使用 Hibernate 3.6 和 MSSQL 2012。

执行此 HQL 时

select tbl.state from Property tbl where tbl.state = 1 and tbl.entity.state = 1 and
tbl.entity.className = 'com....' and tbl.fieldName = 'fieldName'

我收到了这条 SQL

select property0_.State as col_0_0_ from Properties property0_ cross join Entities
entity1_ where property0_.refEntityid=entity1_.id and property0_.State=1 and
entity1_.State=1 and entity1_.ClassName='com....' and property0_.FieldName='fieldName'

*注意 where 子句中的 cross joinadd 条件

根据 Hibernate 文档https://docs.jboss.org/hibernate/core/3.5/reference/en/html/queryhql.html#queryhql-joins-forms

隐式连接应该生成到内连接

我注意到有一个开放的错误https://hibernate.atlassian.net/browse/HHH-7707 可能与此问题有关,但没有人回答,并且已经开放一年了。

如果能提供有关此问题的任何信息,我将不胜感激。谢谢。

PS。我很清楚使用隐式连接不是编写 HQL 的正确方法,但我现在对此无能为力。

【问题讨论】:

  • 哇,这在休眠方面真的很蹩脚和坏掉了。 where foo.bar is not null or foo.bar.baz = x 如果所有 foo 对象都有一个空 bar 引用,则返回完全不合逻辑的零结果...

标签: hibernate hql


【解决方案1】:

您的联接是内联接,但使用的是在 where 子句中添加条件的旧语法:

where property0_.refEntityid=entity1_.id

而不是这样做

inner join Entities entity1_ on property0_.refEntityid=entity1_.id

结果完全一样。

并且在 HQL 中使用隐式连接根本不是问题,只要您了解它们在做什么。

【讨论】:

  • 你说的一切都很好,但这并不能解释为什么我要交叉连接 + 添加 where 条件而不是像文档说的那样正常的内部连接。
  • 阅读您的答案后,我回到了休眠文档中的“连接语法形式”部分并重新阅读了几次。现在我开始意识到那里使用的术语“内连接”并不一定意味着内连接语法,而只是用于可能以两种方式完成的内连接操作,正确的内连接或交叉连接与添加的 where 子句.所以现在,我可以回去吃饭、睡觉和洗澡了,随它去吧。谢谢@jb-nizet
  • 对于信息,我有一个三重交叉连接并添加了 where 子句,在检查了 EXPLAIN 之后,我可以确认我得到了完全相同的执行计划。当我看到其他一些帖子谈到那些由休眠生成的交叉连接很糟糕并且正在改变他们的标准请求时,我有点惊慌失措......事实上,幸运的是我在这里结束了:-)
【解决方案2】:

使用 HQL 时,在执行连接操作时始终使用正确的别名。您的查询应该是这样的:

select tbl.state 
from Property tbl 
left join tbl.entity entity 
where tbl.state = 1 
    and entity.state = 1 
    and entity.className = 'com....' 
    and tbl.fieldName = 'fieldName'

否则如果你尝试使用tbl.entity.someProperty,在HQL中,它总是会创建一个crossJoin

【讨论】:

    猜你喜欢
    • 2013-02-25
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-17
    • 1970-01-01
    • 2013-05-06
    相关资源
    最近更新 更多