为什么在 HQL 中直接使用列名有时只能起作用?

发布于 2024-09-27 19:23:02 字数 422 浏览 0 评论 0原文

我有两个 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 查询有效,但第二个 HQL 查询无效。

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

I have two HQL queries I am using for a quick-and-dirty unit test. The first looks somewhat like this:

from Foo where SOME_FOREIGN_KEY = 42

The second looks like this:

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

The SOME_FOREIGN_KEY column is not the name of something that Hibernate knows is mapped.

For some reason, the first HQL query works, but the second one does not.

My goal here is to get the second version to work, without traversing the object graph to the object identified by the foreign key. For this test, I have a known ID and I only want the objects related to that ID. The object itself on the other end of the relationship is irrelevant. Is this possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

挖个坑埋了你 2024-10-04 19:23:02

由于某种原因,第一个 HQL 查询有效,但第二个 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 的要点之一是抽象表和列名称,在这里您将完全无法实现这一目标。

For some reason, the first HQL query works, but the second one does not.

When you use something that isn't known by Hibernate in the WHERE clause of an HQL query (e.g. a function that is not registered in the SQL dialect), Hibernate acts smartly and passes it directly to the database.

In other words, assuming Foo is mapped on TABLE_FOO, the following HQL

from Foo where SOME_FOREIGN_KEY = 42

is translated into the following SQL

SELECT FROM TABLE_FOO WHERE SOME_FOREIGN_KEY = 42

And works if TABLE_FOO actually has a SOME_FOREIGN_KEY column.

However, when using an alias like in the second example:

from Foo as foo where foo.SOME_FOREIGN_KEY = 42

Hibernate tries to resolve SOME_FOREIGN_KEY as a property of the Foo entity, and this obviously fails.

My goal here is to get the second version to work, without traversing the object graph to the object identified by the foreign key.

It won't if you prefix the column with the alias. So the following should work:

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

But honestly, I don't understand why you don't want to use a path expression and I would advice against using the above solution. One of the the point of HQL is to abstract the table and column names and you would be totally defeating this goal here.

我们的影子 2024-10-04 19:23:02

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

也许这会起作用:

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

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

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

So Foo in first example is without alias and in second it is. This means that in second example Hibernate is looking for property of the 'foo'. This should be the answer.

Maybe this will work:

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

SomeForeignKeyId is property mapped to SOME_FOREIGN_KEY, either way you will have to do this through Id field of referencing entity.

Also fetching Foo as in first example, should work just fine, depending on your mapping. So if in your mapping you have Eager fetching, that should work as far as I know.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文