2009-12-09 18 views
7

Me encontré con algunas preguntas similares en StackOverflow, intenté con las soluciones, pero no encontré una respuesta.Llamada de EclipseLink JPA `@ PreUpdate` no persistiendo

Estoy usando una estrategia de JPA bastante común para establecer los últimos tiempos modificados en algunas entidades. Configure las columnas y los campos, luego marque un método con @PreUpdate y déjelo establecer igual a la hora actual.

El problema es que puedo ver en el depurador que se está llamando al método y que el campo se está actualizando; sin embargo, en mis registros de DB solo veo una llamada SQL para ACTUALIZAR el campo modificado que NO incluye una ACTUALIZACIÓN para el campo de marca de tiempo.

Para complicar aún más las cosas @PrePersist funciona perfectamente, solo @PreUpdate presenta este comportamiento.

La explicación más cercana que he encontrado hasta ahora es en este LINK.

preguntas similares a: # 1725699 y # 1745890

estoy usando EclipseLink v2 y v1 APP para la compatibilidad con GlassFish v2.

He intentado usar ambas anotaciones directamente en los métodos de la clase de entidad, así como un EntityListener unido a la clase de entidad con el @EntityListener anotación.

Sospecho que esto es un error en EclipseLink, pero no lo puedo probar.

Bug o no me gustaría mucho que esta simple operación a trabajar. ¿Hay algo malo con esta implementación? ¿Es este un problema conocido en EclipseLink? ¿Es este un problema conocido en JPA? ¿Hay alguna forma de evitar esto?

En lugar de ir a la base de datos y usar desencadenadores, ¿hay alguna ruta alternativa para que mi código Java establezca la marca de tiempo update_on?

¡Gracias por el consejo!

Los fragmentos de código siguen.

campos

Institución:

@Column(name = "updated_on") 
@Temporal(TemporalType.TIMESTAMP) 
private Date updatedOn; 
@Column(name = "created_on") 
@Temporal(TemporalType.TIMESTAMP) 
private Date createdOn; 

métodos de actualización anotados:

@PreUpdate 
public void setUpdatedOn(Timestamped object) { 
    object.setUpdatedOn(new Date()); 
} 

@PrePersist 
public void setCreatedOn(Timestamped object) { 
    if (object.getCreatedOn()==null) { 
     object.setCreatedOn(new Date()); 
    } 
} 

Respuesta

4

El enlace que se describe exactamente su situación: para la verificación sucia, se detectan campos actualizados antes de llamar al método @PreUpdate y los cambios en el método @PreUpdate no se detectan más. Probablemente esto se haga por razones de rendimiento porque las comprobaciones sucias pueden ser muy costosas en los gráficos de objetos grandes. Parece que ahora sus opciones son usar un mecanismo específico del proveedor (DescriptorEvent) o cambiar a Hibernate.

+0

Felix - Gracias por la aclaración. Pensé que eso era lo que estaba viendo. Veo cómo implementar el manejo del DescriptorEvent, casi tan fácil como anotar algunos métodos. Solo tengo que encontrar el archivo XML correcto para agregar el controlador. ¡Gracias de nuevo! – Freiheit

+0

Hola, Freiheit, estoy enfrentando el mismo problema en este momento, ¿te importaría compartir tu código DescriptorEvent como ejemplo? :) Gracias – sunnycmf

+0

@Freiheit me encantaría ver la solución también. Gracias por adelantado. –

3

Mybe un poco tarde, pero para la integridad de la información esto no es un error, sino un comportamiento documentado:

Fecha o calendario tipos se supone NO para ser mutable por defecto, si se desea para llamar a los métodos establecidos en la fecha o el calendario, entonces la asignación debe establecerse en @Mutable.

Para los tipos de fecha y calendario, la propiedad de persistencia global "eclipselink.temporal.mutable" también se puede establecer en "true".

así, ya sea anotaciones

@Mutable 
@Column(name = "updated_on") 
@Temporal(TemporalType.TIMESTAMP) 
private Date updatedOn; 

o definir

<property name="eclipselink.temporal.mutable" value="true" /> 

en persistence.xml

+0

Muchas gracias, Michele. Me funciona como un encanto. –

+0

De nada :) –

+0

He añadido esta anotación, pero todavía no está funcionando ([vea mi pregunta]) (https://stackoverflow.com/questions/47081932/prepersist-not-working-with-mappedsuperclass-in-hibernate -spring-environment)). ¿Alguna idea de por qué? – displayname

Cuestiones relacionadas