簡體   English   中英

為什么冬眠在執行saveAndFlush之前再次加載實體?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM