【问题标题】:Why does using a column name directly in HQL only work sometimes?为什么有时只能在 HQL 中直接使用列名?
【发布时间】:2010-10-12 17:18:11
【问题描述】:

我有两个 HQL 查询用于快速而肮脏的单元测试。第一个看起来有点像这样:

from Foo where SOME_FOREIGN_KEY = 42

第二个是这样的:

from Foo as foo
 inner join foo.Bar as bar
 where foo.SOME_FOREIGN_KEY = 42

SOME_FOREIGN_KEY 列不是 Hibernate 知道已映射的名称。

由于某种原因,第一个 HQL 查询有效,但第二个无效。

我的目标是让第二个版本工作,而不需要遍历对象图到由外键标识的对象。对于这个测试,我有一个已知的 ID,我只想要与该 ID 相关的对象。关系另一端的对象本身是不相关的。这可能吗?

【问题讨论】:

  • 注意,我将其标记为“nhibernate”和“hibernate”,以防这两者都适用(因为这是一个 HQL 问题),但我实际上使用的是 NHibernate。
  • SOME_FOREIGN_KEY 是 BAR 表的实际键吗?
  • SOME_FOREIGN_KEY 是不在查询中的单独表的外键。

标签: nhibernate hibernate hql


【解决方案1】:

由于某种原因,第一个 HQL 查询有效,但第二个无效。

当您在 HQL 查询的 WHERE 子句中使用 Hibernate 不知道的内容时(例如,未在 SQL 方言中注册的函数),Hibernate 会巧妙地执行并将其直接传递给数据库

换句话说,假设Foo 映射到TABLE_FOO,下面的HQL

from Foo where SOME_FOREIGN_KEY = 42

翻译成下面的SQL

SELECT FROM TABLE_FOO WHERE SOME_FOREIGN_KEY = 42

如果 TABLE_FOO 实际上有一个 SOME_FOREIGN_KEY 列,则可以工作。

但是,当使用第二个示例中的别名时:

from Foo as foo where foo.SOME_FOREIGN_KEY = 42

Hibernate 尝试将SOME_FOREIGN_KEY 解析为Foo 实体的属性,这显然失败了。

我的目标是让第二个版本工作,而不需要遍历对象图到外键标识的对象。

如果您在列前加上别名,则不会。所以以下应该工作:

from Foo as foo
 inner join foo.Bar as bar
 where SOME_FOREIGN_KEY = 42

但老实说,我不明白您为什么不想使用路径表达式,我建议您不要使用上述解决方案。 HQL 的重点之一是抽象表名和列名,您将在这里完全违背这个目标。

【讨论】:

  • 谢谢。我同意我使用的 HQL 不是正确的方法,尤其是鉴于您的回复。 (我将引入一个特定于数据库的依赖项。)事实上,正如我所说,HQL 只是一个快速而肮脏的测试。没有远程生产。
【解决方案2】:

因此,第一个示例中的 Foo 没有别名,而第二个示例中没有别名。这意味着在第二个示例中,Hibernate 正在寻找 'foo' 的属性。这应该是答案。

也许这会起作用:

      select  f
      from    Foo f
      inner join f.Bar bar
      where   f.SomeForeignKeyId = 42

SomeForeignKeyId 是映射到 SOME_FOREIGN_KEY 的属性,无论哪种方式,您都必须通过引用实体的 Id 字段来执行此操作。

也像第一个示例一样获取 Foo,应该可以正常工作,具体取决于您的映射。因此,如果在您的映射中您有 Eager fetching,据我所知,这应该可以工作。

【讨论】:

  • 是的,我可以理解为什么这里可能会有所不同。尽管如此,我还是想弄清楚如何让第二个版本正常工作......
  • 看我的例子。也许它可以提供帮助。
  • 谢谢;这很有帮助,它解决了我的问题,虽然不是我预期的那样。我将列映射为 *(使用您的示例)。这行得通。不过,我仍然想了解为什么在某些情况下使用列名有效,而在其他情况下则无效。
  • 我建议运行 NProf 或设置 "show_sql" 以查看由两个不同查询生成的 SQL,也许这会给表格带来一些有趣的东西。
猜你喜欢
  • 2021-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-17
  • 2018-03-05
相关资源
最近更新 更多