hibernate 和 jpa 的怪异;意想不到的懒惰获取

发布于 2024-11-05 21:38:41 字数 706 浏览 0 评论 0原文

我使用的是相当旧的 Hibernate 版本(3.2.4),所以这可能与此有关。不幸的是,项目要求阻止我升级。

我有一个与 Bar 具有多对一关联的 Foo 类。关联被标记:

lazy="false" fetch="join"

现在,当我执行以下操作时:

em.find(Foo.class, id);

我得到了预期的结果:一条将 FOO 表与 BAR 表连接起来的单个语句。然而,当我尝试类似的操作时:

em.createQuery("select f from Foo where f.id = :id")
.setParameter("id", id)
.getSingleResult();

我得到了单个连接,然后是针对 BAR 的附加选择查询。第二个查询似乎完全是多余的;急切地填充 Foo 实例所需的所有数据应该可以从初始连接中获得。它看起来大致是这样的:

select f.id, f.xyz, ..., b.id, b.xyz, ... 
from foo f 
join bar b on b.id = f.bar_id 
where f.id = ?

select b.id, b.xyz, ... 
from bar b 
where b.id = ?

有什么想法吗?

I'm using a rather old version of Hibernate (3.2.4) so it's possible this is related to that. Unfortunately the project requirements prevent me from upgrading.

I have a class Foo with many-to-one association to Bar. The association is flagged:

lazy="false" fetch="join"

Now when I do something like:

em.find(Foo.class, id);

I get the expected result: a single statement joining the FOO table with the BAR table. However, when I try something like:

em.createQuery("select f from Foo where f.id = :id")
.setParameter("id", id)
.getSingleResult();

I get the single join followed by an additional select query against BAR. The second query seems to be entirely superfluous; all the data needed to eagerly populate an instance of Foo should have been available from the initial join. It looks roughly like this:

select f.id, f.xyz, ..., b.id, b.xyz, ... 
from foo f 
join bar b on b.id = f.bar_id 
where f.id = ?

select b.id, b.xyz, ... 
from bar b 
where b.id = ?

Any thoughts?

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

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

发布评论

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

评论(1

呆头 2024-11-12 21:38:41

执行 HQL 查询时,Hibernate 不尊重 fetch = "join"。来自 文档< /a>:

映射文档中定义的获取策略会影响:

  • 通过 get() 或 load() 检索
  • 导航关联时隐式进行的检索
  • 条件查询
  • 如果使用子选择获取,则进行 HQL 查询

对于 HQL 查询,您必须使用 左连接获取

em.createQuery("select f from Foo f left join fetch f.bar where f.id = :id")
    .setParameter("id", id)
    .getSingleResult(); 

Hibernate doesn't respect fetch = "join" when executing HQL queries. From the documentation:

The fetch strategy defined in the mapping document affects:

  • retrieval via get() or load()
  • retrieval that happens implicitly when an association is navigated
  • Criteria queries
  • HQL queries if subselect fetching is used

In the case of HQL queries you have to use left join fetch:

em.createQuery("select f from Foo f left join fetch f.bar where f.id = :id")
    .setParameter("id", id)
    .getSingleResult(); 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文