2012-06-21 16 views
17

Estoy haciendo una aplicación web con Spring 3.1.0.RELEASE, JSF 2.x, JPA 2 con Hibernate Provider, MySql 5.1.x. La aplicación se ejecuta en Tomcat 7.X.Desencadenantes frente al evento JPA

En mis entidades tengo una fecha como la última fecha de actualización:

@Column(name = "last_update_date", insertable = false, updatable = false) 
@Temporal(TemporalType.TIMESTAMP) 
private Date lastUpdateDate; 

Por el momento tengo un disparador que las actualizaciones:

CREATE TRIGGER upd_site BEFORE UPDATE ON site 
FOR EACH ROW SET NEW.last_update_date = CURRENT_TIMESTAMP(); 

Funciona bien, pero acabo de notar que hay hay algunos métodos de devolución de llamada en JPA http://www.objectdb.com/java/jpa/persistence/event

¿Cuál es el mejor entre los eventos JPA y los desencadenadores de MySql?

Gracias.

Respuesta

13

lo he utilizado en ambos sentidos con disparadores en el PP y con los oyentes de la APP, que se han asentado en los oyentes de la APP, ya que:

  • el único código hablar con la base de datos de código de APP por lo que don' Tengo que preocuparme de que los campos de marca de tiempo no estén actualizados. (Si esto cambia en el futuro, puedo agregar desencadenadores y cambiar mi calic asignado)

  • Los oyentes JPA son menos complejos en el sentido de que no tuve que crear muchos activadores en mi base de datos, así que tenía menos cosas mantener. Como estoy desarrollando y cambiando activamente la estructura db a medida que avanzo, es genial no tener que ir y actualizar los desencadenantes a medida que avanzo rápidamente en el desarrollo.

  • tengo un control completo sobre la base de datos y de hecho una regla para el PP que cada mesa se va a tener una tecla p entero, y una versión número entero, y que las mesas de marca de tiempo tendría insert_ts y update_ts columnas éstos son universales reglas en mi diseño db así que la vida es fácil Tengo estas dos superclases mapeadas que hacen que todas mis aplicaciones sean simples de codificar ya que me extiendo desde ellas.

@MappedSuperclass 
public abstract class PersistableObject { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name="pkey") 
    private Integer pkey; 

    @Version 
    @Column(name="version") 
    private Integer version; 

    public Integer getPkey() { 
     return this.pkey; 
    } 

    public Integer getVersion() { 
     return this.version; 
    } 

    @Override 
    public String toString() { 
     return "Presistable Object: pkey=" + this.pkey + " Object: " + this.getClass().getName(); 
    } 
} 

y

@MappedSuperclass 
public class TimeStampedPersistableObject extends PersistableObject { 

    @Column(name = "insert_ts") 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date insertTimestamp; 

    @Column(name = "update_ts") 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date updateTimestamp; 

    @SuppressWarnings("unused") 
    @PrePersist 
    private void onInsert() { 
     this.insertTimestamp = new Date(); 
     this.updateTimestamp = this.insertTimestamp; 
    } 

    @SuppressWarnings("unused") 
    @PreUpdate 
    private void onUpdate() { 
     this.updateTimestamp = new Date(); 
    } 


    public Date getInsertTimestamp() { 
     return this.insertTimestamp; 
    } 


    public Date getUpdateTimestamp() { 
     return this.updateTimestamp; 
    } 
} 
+3

El único problema con los eventos JPA es ¿qué ocurre si desea actualizar el DB con SQL? Esto omitirá los eventos JPA.En general, la base de datos debe ser autónoma y, por lo tanto, los administradores de bases de datos le indicarán que utilice desencadenantes. Los desarrolladores preferirán los eventos JPA. –

18

No hay mejor cosa. Un activador de la base de datos actualizará la última fecha de actualización en cada actualización de una fila, cualquiera que sea el modo utilizado para actualizar la fila (Hibernate, una consulta JDBC o una actualización de la herramienta de administración de la base de datos). Una devolución de llamada JPA solo se invocará cuando la fila se actualice utilizando JPA. Es posible que desee uno o el otro.

Otra diferencia es que JPA no tiene conocimiento del desencadenador ejecutado por la base de datos. Por lo tanto, si actualiza un campo en su entidad y JPA descarta el cambio, la fecha de actualización será modificada por el desencadenador, pero la entidad JPA mantendrá el antiguo valor de la fecha de actualización en la memoria. Entonces, si esta fecha de actualización se muestra en la GUI después de la actualización, la fecha de actualización será incorrecta. Deberá actualizar la entidad para obtener la fecha de actualización más reciente.

+1

El comentario en el segundo párrafo es muy útil. –

+0

Perfecto conjunto sucinto de diferencias entre el disparador de una base de datos y el método de devolución de llamada JPA. Un trabajo cron también es una buena alternativa si su caso de uso así lo requiere. – HopeKing

Cuestiones relacionadas