【问题标题】:hibernate not doing a eager fetch (using fetch="join" and lazy="false")hibernate 不进行急切获取(使用 fetch="join" 和lazy="false")
【发布时间】:2012-12-20 17:51:14
【问题描述】:

我想在我的 web 应用程序中进行急切的获取。我的映射文件中有以下内容

<many-to-one name="user" class="com.xyz.beans.User" lazy="false" fetch="join">
    <column name="startedBy" />
</many-to-one>
<many-to-one name="participantByParticipant1" class="com.xyz.beans.Participant" lazy="false" fetch="join" cascade="all" >
    <column name="participant1" />
</many-to-one>
<many-to-one name="participantByParticipant2" class="com.xyz.beans.Participant" lazy="false" fetch="join" cascade="all">
    <column name="participant2" />
</many-to-one>

我有一个查询如下

Query query = session.createQuery("from Post as p order by challenge.createdOn desc");
query.setFirstResult(0);
query.setMaxResults(10);

参与者表与其他表有一些映射。它们的获取策略是相同的 执行上述查询大约需要 2 秒以上,我可以看到 hibernate 生成的以下查询 1 选择查询以获取 10 个帖子 20 个参与者表的选择查询(因为每个帖子有 2 个参与者)

1) 为什么会这样?为什么不进行一次连接?
2)我该如何优化呢?它花费了太多时间。该表现在只有 10 条记录

【问题讨论】:

  • "我想在我的网络应用程序中急切地获取所有内容。"。为什么你需要急切地获取所有东西?此外,虽然现在的趋势是使用注释而不是 XML 映射,但 XML 映射并没有错。它大大简化了 DAO。
  • 因为我需要在 UI 上显示它。上面的查询大约需要 2 秒,这太多了。我想一次性在一个 selct 语句中获取所有相关表
  • 如果您使用名为 org.springframework.orm.hibernateX.support.OpenSessionInViewFilter 的过滤器,您可以对 FetchType.LAZY 执行相同操作。它允许在 Web 视图中延迟加载(如您所说的 UI)。
  • 但我不想使用延迟加载。我想使用急切加载。为什么当我明确指定延迟 =“false”时休眠不这样做?延迟加载会导致性能问题。它是上面提到的简单查询需要 2 秒以上,这很糟糕
  • 急切加载往往会导致严重的性能瓶颈,尤其是当您的实体有很多子行时,大约 10000 行。每次加载父实体时都加载它们,即使它们不是必需的,在某种程度上完全没有必要。你怎么看?

标签: java mysql performance hibernate fetch


【解决方案1】:

在你的映射中设置lazy="false" fetch="join"只有当你直接得到你的实体时才会生效:

session.get(Post.class, postId);

当您进行查询时,您需要明确声明您的获取策略。否则还是会偷懒:

from Post as p left join fetch p.user

与往常一样,此规则有许多变体和例外情况。您可以在 Hibernate 文档中找到更多信息,16.3. Associations and joins

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-21
    • 2013-08-30
    • 2010-12-08
    • 1970-01-01
    • 2015-05-08
    • 2013-09-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多