簡體   English   中英

如何使用hibernate-jpa2.0引發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.

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