![](/img/trans.png)
[英]How JPA knows when it have to throw OptimisticLockException?
[英]How to throw OptimisticLockException with hibernate-jpa2.0
我目前正在我的項目中進行樂觀鎖定管理。 我們使用JPA 2.0(hibernate-jpa2.0-api-1.0.1.Final),數據源由JBoss 7提供。
我做了什么
在我的實體“ AccordSimple”中,使用@Version批注:
@Entity
@Table(name = "AccordSimple")
public class AccordSimple {
@Id
@SequenceGenerator(name = "parametresubsidesequence",
sequenceName = "parametresubsidesequence", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "parametresubsidesequence")
private Long id;
// Optimistic lock.
@Version
private Long version;
}
這是我的AccordServiceImpl
public AccordDTO updateAccord(AccordDTO accordDTO) throws AppException {
AccordSimple accord = getAccordRepository().findByReference(
accordDTO.getAccordReference());
if (accord == null) {
return null;
}
// copy new values from the DTO...
accord.setVariable(accordDTO.getVariable());
// ...
// Set the version from the DTO (old version if someone changes before me!)
accord.setVersion(accordDTO.getVersion());
getAccordRepository().merge(accord);
return accordDTO;
}
這樣,就不會拋出OptimisticLockException。 即使合並前在juste中包含的版本在我的數據庫中的版本之下。
我已經找到了原因。 這是負責的:
AccordSimple accord = getAccordRepository().findByReference(
accordDTO.getAccordReference());
因為如果我將方法更改為:
public AccordDTO updateAccord(AccordDTO accordDTO) throws AppException {
AccordSimple accord = new AccordSimple(accordDTO.getAccordReference(), accordDTO.getVersion());
// copy new values from the DTO...
accord.setVariable(accordDTO.getVariable());
// ...
// Set the version from the DTO (old version if someone changes before me!)
accord.setVersion(accordDTO.getVersion());
getAccordRepository().merge(accord);
return accordDTO;
}
會拋出OptimisticLockException!
問題
該版本來自Hibernate緩存,而不來自我的DTO。 因此,如果我分離實體,那么一切都會正常工作(我想),但是我不想這樣做(如果開發人員忘記了它,則會產生錯誤源……)。
你有什么主意嗎
[編輯]可能的選擇:還沒有嘗試過,您可以嘗試一下:
通過使用@PostLoad或帶有insertable = false,updateable = false的額外列映射,在實體中保留額外的版本號。
使用@PreUpdate方法檢查版本字段和Extra-version字段。 如果它們不匹配,則拋出異常。
所有這些都可以放在基本模型類中。 因此,沒有人會忘記將邏輯放入實體中:)
(原始信息)
這正是我在上一個項目中所面臨的。 執行樂觀鎖驗證時,Hibernate不會查看實體中的version字段。
解決時間的方法是在將DTO“合並”到實體時驗證自己。 那時,我有一個實用程序可以在DTO和Entity之間映射屬性。 版本檢查只是DTO版本字段中的一個額外注釋問題,而不是將值設置為相應實體的屬性,而是在不匹配時引發異常。
雖然可能不適用於您
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.