2011-03-14 124 views
7

我有兩個班說Foo和Bar映射爲@OneToOne(雙向)使用Hibernate(3.6.1最終)與JPA(2.0)一樣 -更新休眠手動版

@Entity 
public class Foo{ 
    @Id 
    private Long id; 

    @OneToOne(cascade = CascadeType.ALL, mappedBy = "foo") 
    private Bar bar; 

    @OneToOne(cascade = CascadeType.ALL, mappedBy = "foo") 
    private Qux qux; 

    @Version 
    private int version; 

    // getters and setters omitted 
} 

@Entity 
public class Bar{ 
    @Id 
    private Long id; 

    @OneToOne 
     @JoinColumn(name = "foo_id", nullable = false) 
    private Foo foo; 

    // getters and setters omitted 
} 

@Entity 
public class Qux { 
    @Id 
    private Long id; 

    @OneToOne 
     @JoinColumn(name = "foo_id", nullable = false) 
    private Foo foo; 

    // getters and setters omitted 
} 

注意 - 酒吧和Qux沒有@Version

如果我們更新Bar,那麼hibernate不會增加Foo的版本,Qux也是一樣。但是我們的業務邏輯需要 - 如果有人更新Foo中的Bar,並且其他線程正在嘗試更新同一個Foo的Qux,但沒有更新Bar,反之亦然,則此類更新應該失敗。
因爲如果我們更新Bar,hibernate不會更新Foo的版本屬性,所以如果我們更新Bar和Qux,我們決定手動更新Foo的版本(我知道這很奇怪,不推薦)。
它工作得很好..但我擔心一些併發的角落情況可能會失敗,或將有意想不到的行爲。
爲此目的進行這種類型的版本調整是否安全?或有任何其他更好的這種另類(我已經嘗試過樂觀/悲觀力increament)

回答

10

正確的方法來強制版本更新如下:

em.lock(entity, LockModeType.OPTIMISTIC_FORCE_INCREMENT); 

它打算在這樣的使用案例。

其他方法EntityManager也可以使用LockModeType也可以使用。

+0

但要使用此我需要Bar和Qux中的版本屬性,對不對? – Premraj

+0

@Premraj:是的.. – axtavt

+0

我正在嘗試這個代碼: 'Foo entity = new Foo(); em.persist(foo); int oldVersion = entity.getVersion(); em.lock(entity,LockModeType.OPTIMISTIC_FORCE_INCREMENT); return oldVersion == entity.getVersion();' 我希望這是錯誤的,但它是真實的。 –