【问题标题】:Eager loading despite Lazy Initialization?尽管有延迟初始化,但仍渴望加载?
【发布时间】:2023-03-17 22:27:01
【问题描述】:

我们有一个实体,它有很多 ManyToOne、OneToOne 等关系,它们自己又具有一些关系。 例如

@OneToMany(targetEntity = Season.class, cascade = {
    CascadeType.ALL
})
@JoinColumn(name = "SEASON_ID")
  public List<Season> getSeasons(){...}

(我无法更改)。

这些都是延迟加载的(我认为默认情况下),这很好,我们不想改变它。 现在我们有这种情况,我们希望通过它的 id 急切地找到整个实体并返回它。

我发现了很多更改实体的建议,以及关于急切加载还是延迟加载更好的讨论,目前这对我没有帮助,因为实体对我们来说是遥不可及的。 有没有办法做到这一点,而无需更改实体并且不必调用所有可能的 getter 来初始化惰性实体(因为这些实体太多了)? 例如,Question 24573877 的答案对我不起作用。

基本上我想说“急切地加载实体,但只是这一次”。 目前我只是在做return em.find(MyEntity.class, contractId)(我可以改变这个)。

感谢和问候 Urr4

【问题讨论】:

    标签: java hibernate lazy-evaluation eager


    【解决方案1】:

    看:http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html

    第 14.3 章。关联和连接

    “获取”连接允许使用单个选择来初始化值的关联或集合以及它们的父对象。这在集合的情况下特别有用。它有效地覆盖了关联和集合的映射文件的外部连接和惰性声明。有关详细信息,请参阅第 19.1 节“获取策略”。

    您必须编写查询而不是使用 em.find。

    以这个查询为例:

    从猫当猫 内连接获取 cat.mate left join fetch cat.kittens

    将返回已经加载(渴望)的伴侣和小猫的猫,即使它们已经在惰性中初始化

    编辑: 或者你可以使用 fetch profile :

    为了缓解这些问题,Hibernate 提出了一种不在映射级别而是在请求级别上工作的获取策略。因此,您仍然可以有延迟加载映射,但在某些情况下急切获取。

    看:https://blog.frankel.ch/hibernate-hard-facts-part-6

    【讨论】:

    • 感谢您的回答,但如果在您的示例中,小猫的“兄弟”也是小猫,该怎么办。我是否必须在查询中做更多的 fetch join 才能急切地加载它们?在我的情况下,数据模型非常复杂且非常庞大,我希望避免将每个子实体都添加到查询中。
    • 您必须添加与lazy 中的关系一样多的 fetch ,我认为即使对于 1 或 2 个查询很复杂,您也可以这样做。如果您意识到您经常需要检索实体关系,您将不得不重新考虑该实体的负载配置。祝你好运!
    • 好的,很高兴知道,但遗憾的是这只对我有一点帮助。就像我说的,这个实体很大,有很多关系,其中很多我都不知道。编写语句而不是调用每个 getter 可能更容易,但我仍然需要了解实体的各个方面来构建语句。我希望有办法避免这种情况。延迟初始化是我们领域中的最佳选择,只是不是在这种情况下,所以我不想更改它。
    • 我明白了,您可以使用 fetchprofile,让延迟加载映射但在某些情况下急切获取。看blog.frankel.ch/hibernate-hard-facts-part-6
    • 谢谢,这看起来是正确的方法 :)- 仍然存在一个问题,即我不知道实体内部的大多数关联,其中许多关联本身就有关联。我不想添加大量的获取配置文件来获取实体的深层副本。感觉应该有更简单的方法。在获取配置文件方面,我正在寻找类似@FetchProfile(fetchOverrides = { @FetchOverride(association =ALL, entity = MyEntity.class, mode = FetchMode.JOIN) }, name = “LOAD-DEEP-CLONE-EAGERY”)
    【解决方案2】:

    我并没有真正按照我想要的方式解决它,但它现在可以工作了。 看来,真的没有办法急切地加载实体,您对此一无所知。 我们的问题是,该实体来自第 3 方 Maven 依赖项,并且不可更改且难以查看。 最后,我们构建了一个 entityProcessor,它获取延迟加载的实体并递归调用每个 getter 和子实体的所有 getter。 如果我们可以控制一个实体,我下次会使用 FetchProfiles,否则,我建议实现一个 clone() 函数。

    【讨论】:

      猜你喜欢
      • 2016-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-10
      • 1970-01-01
      • 2011-11-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多