【问题标题】:Preserve object identity in parent-child relations of a Hibernate model在 Hibernate 模型的父子关系中保留对象身份
【发布时间】:2022-10-12 21:32:18
【问题描述】:

我有以下情况,到目前为止找不到任何解决方案。

想象一下下面的 Hibernate 模型,它包含 3 种不同类型的一对多关系:

public class A {
  
  @Transient
  private String someRuntimeData;

  @OneToMany
  private Set<B> collA;

  @OneToMany 
  private Set<C> collB;
}


public class B {
  @ManyToOne
  private A parent;
}


public class C {
  @ManyToOne
  private A parent;
}

想象一下,数据库包含许多 B'c 和 C,它们可能与 A 有或可能没有父关系。我需要创建一个包含所有 B 和所有 C 的内存缓存,不幸的是,在涉及的不同位置有很多瞬态数据,这需要我禁止缓存同一父对象 A 的多个实例。

class SomeClass {
     @Transactional
     protected void init() {
       bList = repoB.readAll();
       cList = repoC.readAll();
     }
  }

问题是我不知道如何或是否有可能告诉 JPA/Hibernate 以下列方式保留和重用先前加载的实体的对象实例(及其标识):

加载 B 的完整集合及其可选的 A 父集合,然后加载 C 的完整集合,其中重用任何可传递加载的 A 实例(通过 B)。在适当的情况下,B 和 C 实例都指向同一个内存对象。

如果有人能在我吞下苦果并手动重新映射所有内容之前解释如何使用 JPA/Hibernate 的开箱即用功能来实现这一点,我将非常感激。

先感谢您!

【问题讨论】:

  • 基本上,这就是在单个事务中发生的事情。
  • 这就是我的想法,并且我注释了包含对 B 和 C 的 JPA readAll() 调用的方法,但是相同的父对象具有不同的对象身份。 Spring 是否会通过错误或警告告诉我事务上下文实际上并未应用于该方法,或者只是默默地失败?
  • 您使用@Transactional 注释了 readAll() 或包含此方法的类?
  • @Mihe我添加了一个额外的代码sn-p regrding“@Transactional”部分。
  • 您可以尝试调试它,例如。 G。 this answer 可能会有所帮助。

标签: java hibernate jpa object-identity


【解决方案1】:

从提供的代码 sn-ps 看,在这种情况下可能出现的问题并不明显。

为了全面披露,init() 方法是通过类构造函数的自调用调用的:

@Component
class SomeClass {
    
    public SomeClass() {
      init();
    }

    @Transactional
    protected void init() {
      bList = repoB.readAll();
      cList = repoC.readAll();
    }
}

由于我没有为加载或运行时配置任何方面编织,编译器为SomeClass 创建了一个默认的 Spring 代理对象。因此,在进行自我调用时,任何代理逻辑都会被完全规避。 结果,唯一打开的事务是默认的,每个读取操作的专用事务,以及冗余加载的共享父对象。

【讨论】:

    猜你喜欢
    • 2020-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-02
    • 2021-12-05
    • 2017-11-23
    • 2020-03-21
    • 1970-01-01
    相关资源
    最近更新 更多