![](/img/trans.png)
[英]When I do saveAndFlush on an entity object, I see hibernate generates 2 update queries. Why is it and how to avoid it?
[英]Why is hibernate loading an entity again before doing saveAndFlush?
我使用帶有Hibernate的Spring數據作為JPA實現。
在某個時候,我裝載了一輛汽車,操縱它並保存了它。 使用Spring JPA存儲庫,代碼如下所示:
@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批注或字節碼修改,以使臟檢查更加有效。
在同一事務中執行某些保存/刪除操作后,每次有SELECT語句時,Hibernate都會進行臟檢查。 進行臟檢查以清除第一級/第二級緩存。 大致來說,Hibernate通過HashMap進行查找,其中包含緩存表的名稱,並與您的請求中使用的表進行比較。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.