我有以下场景,到目前为止还找不到任何解决方案。
想象一下,下面的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有父关系,也可能与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的开箱即用功能来实现这一点,我将不胜感激。
提前谢谢!
从提供的代码片段中看,在这种情况下问题可能是什么并不明显。
为了完全公开,init()
方法是通过类构造函数的自调用调用的:
@Component
class SomeClass {
public SomeClass() {
init();
}
@Transactional
protected void init() {
bList = repoB.readAll();
cList = repoC.readAll();
}
}
由于我没有为加载或运行时配置任何方面编织,因此编译器为SomeClass
创建了一个默认的Spring Proxy对象。因此,当进行自调用时,可以完全绕过任何代理逻辑。结果,只有在默认情况下打开的事务,每个读取操作的专用事务,以及冗余加载的共享父对象。