gpt4 book ai didi

java - 为什么 hibernate 在执行 saveAndFlush 之前再次加载实体?

转载 作者:行者123 更新时间:2023-12-01 09:30:12 24 4
gpt4 key购买 nike

我使用 Spring Data 和 Hibernate 作为 JPA 实现。

有时我会装载一辆车,操纵它并保存它。使用 Spring JPA-Repository 的代码如下所示:

@Entity @DynamicUpdate @DynamicInsert
public class Car{
@PostLoad
void postLoad(){ log.debug("post load"); }

@PrePersist @PreUpdate
void preSave(){ log.debug("prePersist/preUpdate"); }

/*..*/
}

@Repository
public interface CarRepository extends JpaRepository<Car, Integer>{}

@Controller
public CarController{
public void businessLogic(){
Car car = carRepo.findOne(1); // SELECT ...
log.debug("Car loaded");
car.setColor("red");
// ...
carRepo.saveAndFlush(car); // UPDATE car SET ... <-- !!!
}
}

这在所有自动化测试和 99% 的生产中都运行良好。大多数情况下,包含事务日志和 SQL 的日志如下所示:

SQL: select ... from Car ...
Car: post load
Car loaded
Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.saveAndFlush]
Car: prePersist/preUpdate
SQL: update Car set ...
Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.saveAndFlush]

只有少数情况下,hibernate 在 UPDATE 之前执行 SELECT

SQL: select ... from Car ...
Car: post load
Car loaded
Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.saveAndFlush]
SQL: select ... from Car ...
Car: post load
Car: prePersist/preUpdate
SQL: update Car set ...
Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.saveAndFlush]

有人可以解释一下在什么情况下进行第二次选择吗?我看不到它。

最佳答案

这是 Hibernate 进行脏检查。它会重新加载实体以将其与您保存的任何更改进行比较。

有多种方法可以减轻其性能影响,例如使用版本控制:Java - JPA - @Version annotation或修改字节码以使脏检查更加有效。

关于java - 为什么 hibernate 在执行 saveAndFlush 之前再次加载实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39496525/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com