我使用spring-boot 1.5.4和hibernate-core 5.2.10。在事務結束時彈簧引導不需要的SQL UPDATE
我有一個控制器,它調用一個服務方法(可以將其命名爲pService)保存一個實體的一些邏輯之後
pService.save是這樣的:
@Transactional(readOnly = false, rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public <S extends SomeEntity> S save(S entity) throws ServiceException {
//some logic
entity.setAttrX("original text");
S justSavedEntity = someEntityRepository.save(entity); // POINT 1
//we termporarily change one attribute just to get a legible representation calling another service method (lets name it eService)
eService.process(justSavedEntity);
return justSavedEntity; //POINT 2
}
eService.process是什麼像這樣:
@Transactional(readOnly = false, propagation = Propagation.MANDATORY)
public void process(SomeEntity entity) {
//some logic
entity.setAttrX("someText");
//method ends here
}
因爲沒有其他呼叫分開一個保存點1,我期待文本「原文」被保存在數據庫中,但文我得到保存是在第2點更改的文本。
那麼,爲什麼我要保存「someText」而不是「原始文本」?
我可以在數據庫日誌中看到,在POINT 1之後運行SQL INSERT命令並且pService返回時,以及不需要的SQL UPDATE命令運行時,將「原始文本」更改爲導致錯誤的「someText」。
爲什麼這個「多餘的」UPDATE命令發出?
在此先感謝!
非常感謝您的回答。這很奇怪,因爲我們只有在升級到spring-boot 1.5,1.1和1.2後纔會看到這種行爲需要一個repository.save調用來保存一個實體。任何想法改變了? – Dreal
對於你所看到的有太多可能的解釋,所以對你的問題的任何迴應都是純粹的推測。但是你應該知道,這個行爲是核心JPA規範的一部分,並且一直以這種方式在Spring的jpa子系統中實現。 –
另外,我編輯了答案,在最後添加了相關內容。 –