2011-03-14 28 views
7

Ho due classi dire Foo e Bar mappati come @OneToOne (bidirezionale) usando Hibernate (3.6.1 finale) con JPA (2.0) come -Aggiornamento hibernate versione manualmente

@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 
} 

Si noti che - Bar e Qux non ha @Version colonna

Se aggiorniamo la barra, la sospensione non incrementerà la versione di Foo e lo stesso per Qux. Ma la nostra logica di business ha bisogno di: se qualcuno aggiorna la barra in Foo e altro thread sta tentando di aggiornare la Qux della stessa Foo ma non ha la barra aggiornata e viceversa, tali aggiornamenti dovrebbero fallire.
Poiché Hibernate non aggiorna la proprietà di versione di Foo se aggiorniamo la barra, abbiamo deciso di aggiornare la versione di Foo manualmente (so che è piuttosto strano e sconsigliato) se aggiorniamo la barra e Qux.
Funziona perfettamente bene .. ma sono preoccupato per alcuni casi d'angolo in concorrenza che potrebbero fallire o avere un comportamento non intenzionale.
È sicuro eseguire questo tipo di modifica con la versione per questo scopo? O c'è qualche altra alternativa migliore a questo (ho già provato ottimisti/pessimisti forza increament)

risposta

10

Il modo corretto per forzare l'aggiornamento di versione è la seguente:

em.lock(entity, LockModeType.OPTIMISTIC_FORCE_INCREMENT); 

E 'destinato ad essere utilizzato in tale casi.

Altri metodi di EntityManager che richiedono LockModeType possono anche essere utilizzati.

+0

ma per usare questo ho bisogno di una proprietà di versione in Bar e Qux, giusto? – Premraj

+0

@Premraj: Sì .. – axtavt

+0

Sto cercando di utilizzare questo codice: 'Foo entity = new Foo(); em.persist (foo); int oldVersion = entity.getVersion(); em.lock (entità, LockModeType.OPTIMISTIC_FORCE_INCREMENT); return oldVersion == entity.getVersion(); ' Mi aspetto che questo sia falso, ma è vero. –

Problemi correlati