2011-03-14 16 views
7

Tengo dos clases decir Foo y Bar asignan como @OneToOne (bidireccional) usando Hibernate (3.6.1 final) con APP (2.0) como -actualización de la versión de hibernación 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 
} 

Tenga en cuenta que - Bar Qux no tiene @Version columna

Si actualizamos la barra, hibernación no incrementará la versión de Foo y lo mismo para Qux. Pero nuestra lógica de negocio necesita: si alguien actualiza Bar en el Foo y otro hilo intenta actualizar el Qux del mismo Foo pero no tiene barra actualizada y viceversa, dichas actualizaciones deberían fallar.
Desde hibernación no actualiza la propiedad versión de Foo si actualizamos la barra, hemos decidido actualizar la versión de Foo manualmente (Sé que es bastante raro y no se recomienda) si actualizamos la barra y Qux.
Funciona perfectamente bien ... pero me preocupan algunos casos de esquina en concurrencia que pueden fallar o tendrán un comportamiento involuntario.
¿Es seguro hacer este tipo de modificación con la versión para este propósito? O ¿hay alguna otra alternativa mejor a esto (ya he intentado optimista/increament fuerza pesimista)

Respuesta

10

La forma correcta para forzar la actualización de versiones es el siguiente:

em.lock(entity, LockModeType.OPTIMISTIC_FORCE_INCREMENT); 

Está pensado para ser utilizado en tales casos.

También se pueden usar otros métodos de EntityManager que toman LockModeType.

+0

pero para usar esto necesito una propiedad de versión en Bar y Qux, ¿verdad? – Premraj

+0

@Premraj: Sí .. – axtavt

+0

estoy tratando de utilizar este código: 'entidad Foo = new Foo(); em.persist (foo); int oldVersion = entity.getVersion(); em.lock (entidad, LockModeType.OPTIMISTIC_FORCE_INCREMENT); volver OldVersion == entity.getVersion(); ' espero que esto es falso, pero es cierto. –

Cuestiones relacionadas