2009-09-14 12 views
12

bloqueo optimista con el atributo de versión de una entidad que funciona bien y es fácil de implementar:¿Cómo utilizar la propiedad de versión de bloqueo optimista de Hibernate en la interfaz?

<version property="VERSION" type="int" column="EX_VERSION" /> 

La entidad tiene una propiedad del siguiente tipo:

private int VERSION; 
public int getVERSION() { return VERSION; } 
public void setVERSION(int VERSION) { this.VERSION = VERSION; } 

Hasta ahora, todo bien. Ahora los métodos de servicio devuelven un objeto de transferencia de datos (DTO) para la entidad anterior, que las vistas muestran en HTML. Para las páginas de actualización, el atributo VERSIÓN se almacena en un campo oculto de HTML y se envía con el formulario.

El objetivo es utilizar la propiedad de versión para garantizar que la actualización de un usuario falle si la información que se muestra va acompañada de una versión anterior.

El controlador responde a una solicitud de actualización del usuario invocando un método de servicio con el DTO que contiene la información actualizada (incluyendo la propiedad de versión) y el método de servicio utiliza un objeto de acceso a datos (DAO) para conservar los cambios:

public void update(SimpleDTO dto) { 
    SimplyEntity entity = getSimpleDao().load(dto.getId()); 
    copyProperties(dto, entity); // all properties, including VERSION copied to entity 
    getSimpleDao().update(entity); 
} 

el problema es que la propiedad de versión copiada en la entidad por copyProperties (...) no es respetado por Hibernate. Seguí el motivo en el siguiente foro: https://forum.hibernate.org/viewtopic.php?f=1&t=955893&p=2418068

En resumen, cuando se invoca load(), Hibernate almacena en caché la propiedad de versión en la memoria caché de la sesión y no importa a qué se cambie su valor posteriormente. Acepto que este es el comportamiento correcto, pero Bosses me ha ordenado que apruebe la versión a través de una propiedad de formulario HTML (si hay un patrón mejor para esto, me encantaría escucharlo).

Una solución que estoy explorando ahora es desalojar a la entidad de la sesión después de que se haya configurado su versión usando hibernateTemplate.evict (simpleEntidad) antes de que ocurra la actualización. Espero que esto funcione, pero no parece eficiente.

Me gustaría pedirle a Hibernate que compruebe la propiedad de la versión en la instancia misma, en lugar de solo desde el caché de la sesión.

Gracias de antemano por las respuestas!

- LES

+3

evict() 'la entidad de la sesión funciona. :) dejando abierto para ver si hay respuestas perspicaces ... – les2

Respuesta

10

¿Usted realmente necesita utilizar DTO? No hubieras tenido este problema si estuvieras pasando la entidad real, ni tendrías que volver a cargar la entidad, lo cual no es exactamente bueno para el rendimiento.

Pero incluso si tiene una razón legítima para usar DTO, no entiendo muy bien por qué trataría de actualizar el número de versión en su entidad recién recargada antes de guardar. Considerar diferentes escenarios posibles en el flujo de trabajo:

  1. Entidad se carga inicialmente, tiene la versión V1 =
  2. Se transfiere al DTO que va a la interfaz de usuario, vuelve y está listo para ser salvado.
  3. Entidad está cargado de nuevo, tiene la versión V2 =

Tiene dos posibilidades: ahora

  1. V1 V2 ==. Peachy, no tienes que hacer nada.
  2. V1 es menor que V2, lo que significa que la entidad fue actualizada por otra persona mientras la editaba. No hay ninguna razón para tratar de establecer la versión en V1 e intentar guardar porque fallará el almacenamiento. Puede guardarlo con V2 (anulando así los cambios de otra persona) o puede fallar ahora (sin involucrar a Hibernate).
+1

1. La recarga puede ser necesaria, ya que el DTO puede no contener todos los campos de la entidad, solo un subconjunto. 2. Como se comentó (y también se puede leer en el enlace en la parte inferior de https://forum.hibernate.org/viewtopic.php?t=977889a), el desalojo puede ayudar aquí. – ron

Cuestiones relacionadas