【发布时间】:2021-07-16 11:18:08
【问题描述】:
我知道标题很混乱,问题也是如此。我正在使用 JPA 存储库进行 Spring Boot,但发生了一些异常行为。
我进行了一个存储库调用来获取一个对象,比如说obj1,我对其进行了一些更改,然后我将obj1 传递给了另一个函数funcInSameClass(obj1),它在同一个类中,并且我从那个函数传递了将obj1 转换为自动装配组件AutowiredClass1 的函数funcInAutowiredClass1(obj),从该组件我将obj1 的ID 传递给自动装配组件funcInAutowiredClass2(obj1.id) 的另一个函数funcInAutowiredClass2(obj1.id)。在funcInAutowiredClass2(obj1.id) 中,我调用了存储库以获取与obj1 相同的对象,并在obj1 和saveAndFlush 中对数据库进行了一些更改。
class MainClass {
@Autowired
AutowiredClass1 autowiredClass1;
public void main() {
//inital object after first repository call
Object obj1 = repo.findById(id);
//make some changes in obj1
obj1 = repo.saveAndFlush(obj1);
funcInTheSameClass(obj1);
repo.saveAndFlush(obj1)
log.info(obj1); //here also obj1 name is now XYZ
}
void funcInTheSameClass(Object obj1) {
autowiredClass1.funcInAutowiredClass1(obj1);
log.info(obj1); //here obj1 name is now XYZ
}
}
class AutowiredClass1 {
@Autowired
AutowiredClass2 autowiredClass2;
public void funcInAutowiredClasss1(Object obj1) {
autowiredClass2.funcInAutowiredClass2(obj1.id);
log.info(obj1); // now obj1 name is now XYZ
}
}
class AutowiredClass2 {
public void funcInAutowiredClasss2(int id) {
Object obj2 = repo.findById(id);
obj2.setName("XYZ");
repo.saveAndFlush(obj2);
log.info(obj2); // here I set the obj2 name as "XYZ"
}
}
您可以看到在funcInAutowiredClass2 中,obj1 的引用没有被传递,而是从存储库中获取一个新的实体并更新并保存。那么这些变化是如何反映在 main function() 中的。
【问题讨论】:
-
vladmihalcea.com/jpa-hibernate-first-level-cache看看这篇文章,Hibernate中一级缓存是这样工作的
-
@DanilaZharenkov 你能通过问题中的例子来解释一下这个缓存是如何完成的吗?
-
第一次调用
Object obj1 = repo.findById(id);后,您的实体存在于 PersistenceContext(L1 缓存)中。每次刷新后 - Hibernate 将持久性上下文中的实体状态与数据库中的实体状态同步。在第二次调用findById时,Hibernate 首先检查缓存。具有此类 ID 的实体已经存在,因此 Hibernate 获取缓存的实体。同样重要的是——Hibernate 为实体使用代理,您的 obj1 和 obj2 是持久性上下文中同一实体的代理。这就是为什么 obj1 反映了对实体所做的所有更改 -
@DanilaZharenkov 感谢您的详细解释。签出这个问题,在案例 1 中,为什么这种情况不适用于那里? stackoverflow.com/questions/68406919/…
标签: java spring spring-boot jpa spring-data-jpa