2010-09-20 12 views
5

Tenemos un requisito en nuestro proyecto, donde tenemos que mantener un tipo de historial de los cambios que se realizan a ciertas entidades en la aplicación. The the application es una aplicación web de Java basada en Struts, Spring e Hibernate. ¿Qué tipo de enfoques se han utilizado en este caso?Logging Cambios de la entidad en la aplicación web Java

  • Disparadores en las tablas respectivas es una idea, pero no son fáciles de mantener? y quizás tampoco deberían ser parte de las transacciones (está bien si los desencadenadores fallan, pero las transacciones de actualización de la entidad no deberían fallar).
  • Utilice AoP para esto ya que es una preocupación transversal, pero tiene que ser realmente granular, como al capturar solo los valores cuando la entidad cambia. (Todas las ediciones no tienen sus correspondientes métodos diferentes ... muchas ediciones ocurren en un único método de Java).
  • Utilice Hibernate Event Listeners.

¿Hay algún otro enfoque para realizar este tipo de actividad?

Respuesta

3

Debido a que usted ha dicho

Todas las ediciones no tienen sus métodos diferentes correspondientes ... muchos cambios ocurren en un solo método Java

Incluso si su método de recibir tan sólo un argumento como parámetro y puede recuperar sus relaciones, AOP todavía puede ser una buena idea. Le aconsejo encarecidamente que vea este nice article

La documentación de Hibernate sí dice:

Hibernate Interceptor permite la aplicación de inspeccionar y/o manipular las propiedades de un objeto persistente antes de guardarlo, actualización, supresión o cargado . Un posible uso de esto es rastrear la información de auditoría.

Pero también dice

Asegúrese de que no almacena los estados sessionspecific, ya que múltiples sesiones utilizarán este interceptor potencialmente concurrente

Si utiliza una transacción primavera logrado , puede obtener la sesión asociada al hilo actual usando sessionFactory.getCurrentSession();

public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) { 
    if(entity instanceof SomeEntity) { 
     Session session = sessionFactory.getCurrentSession(); 

Ver getCurrentSession() documentación

Si no es así, se debe crear un interceptor de hibernación locales (que se adjunta a la sesión abierta) en lugar de un interceptor mundial (que se adjunta a la SessionFactory), y luego, se nombraron su sesión

AuditableInterceptor interceptor = new AuditableInterceptor() 
Session session = sessionFactory.openSession(interceptor); 

/** 
    * do it before processing anything if you use local interceptor 
    */ 
interceptor.setSession(session); 

sobre disparadores, que depende de otras cuestiones como la administración de base de datos (que tiene acceso a la administración de DB. Si no es así, hable con DBA es la mejor opción).

+0

Gracias por la información Arthur. Para la implementación simple, estoy tratando de extender Hibernate Event Listener. –

+0

+1, para la explicación de propósito general. – Bozho

+0

+1 como Bozho dijo –

4

JBoss Envers admite la audición y el control de versiones: echa un vistazo.

+0

Interesante (+1) ¿Lo usa con éxito? –

+0

@Arhtur - no, ¡ay! Pero conozco personas que lo usan y dicen que es bueno :) – Bozho

+0

Y +1 también. Envers parece encajar bien aquí. –

Cuestiones relacionadas