Auditoría de Entidades con Listeners Personalizados en Spring

Clase 23 de 25Curso de Java Spring Data JPA: Bases de Datos

Contenido del curso

Spring Data Repositories

Resumen

Controlar cada movimiento que ocurre sobre una entidad es fundamental para mantener la trazabilidad de los datos en cualquier aplicación. Más allá de registrar fechas de creación o modificación, es posible construir un sistema de auditoría completo que capture el estado anterior y posterior de cada cambio usando listeners personalizados en Spring Data JPA.

¿Cómo crear un listener de auditoría para una entidad?

El primer paso es organizar el proyecto creando un paquete dedicado a la auditoría, por ejemplo audit, dentro de la capa de persistencia. Allí se agrupan todas las clases relacionadas, incluyendo AuditableEntity y los listeners que se necesiten [01:00].

La clase central es AuditPizzaListener, que contiene métodos anotados con las callbacks del ciclo de vida de JPA:

  • @PostPersist: se ejecuta después de insertar un nuevo registro en la base de datos.
  • @PostUpdate: se ejecuta después de actualizar un registro existente.
  • @PreRemove: se ejecuta antes de eliminar un registro, permitiendo capturar su estado previo a la eliminación [02:15].
  • @PostLoad: se ejecuta después de que un SELECT carga la información en la entidad.

Un mismo método puede llevar varias anotaciones. Por ejemplo, onPostPersist puede recibir tanto @PostPersist como @PostUpdate para manejar ambos eventos en un solo lugar [01:42].

java @PostPersist @PostUpdate public void onPostPersist(PizzaEntity entity) { System.out.println("Post persist or update"); System.out.println("Old value: " + this.currentValue); System.out.println("New value: " + entity.toString()); }

Cada método debe ser público, no retornar nada (void) y recibir como parámetro el entity correspondiente.

¿Cómo registrar el listener en la entidad?

Para que JPA reconozca el listener, se agrega dentro de la anotación @EntityListeners en la entidad. Cuando ya existe más de un listener, se colocan entre llaves separados por coma [03:25]:

java @EntityListeners({AuditingEntityListener.class, AuditPizzaListener.class})

Además, es necesario implementar el método toString() en PizzaEntity para visualizar el estado del objeto en consola durante las pruebas.

¿Cómo capturar el estado anterior de una entidad antes de modificarla?

El verdadero poder de la auditoría aparece cuando se compara el valor antiguo con el nuevo. Para lograrlo se utiliza @PostLoad junto con un atributo interno llamado currentValue dentro del listener [05:30].

Cuando JPA ejecuta un SELECT y carga los datos, el método anotado con @PostLoad almacena una copia clonada del entity:

java @PostLoad public void postLoad(PizzaEntity entity) { System.out.println("Post load"); this.currentValue = (PizzaEntity) SerializationUtils.clone(entity); }

Se usa SerializationUtils.clone() de Spring Framework en lugar de una asignación directa. Esto es crítico: si se asigna currentValue = entity, ambas variables apuntan a la misma posición en memoria, y al modificar una se modifica la otra, perdiendo la referencia al estado original [06:22].

Para que la clonación funcione, PizzaEntity debe implementar la interfaz Serializable.

¿Qué ocurre al crear un registro nuevo?

Cuando se inserta una pizza nueva, no existe un SELECT previo que dispare @PostLoad. Por eso currentValue conserva el valor de la última carga o queda en null [08:40]. Es importante validar que el ID del entity coincida antes de comparar valores, evitando así un NullPointerException y asegurando que la auditoría refleje el registro correcto.

¿Cuáles son las limitaciones de este tipo de auditoría?

Esta estrategia solo funciona con los métodos del ciclo de vida de los Spring Data Repositories, como save(), delete() o findById() [10:28]. Los queries nativos, por ejemplo uno que actualice precios directamente con SQL, no pasan por el ciclo de vida de las entidades y, por tanto, no disparan los listeners.

Una vez capturados los cambios, la información puede enviarse a:

  • Una base de datos de auditoría dedicada.
  • Archivos de logs.
  • Cualquier sistema externo de monitoreo.

Con esta implementación se tiene control total sobre las operaciones de creación, actualización y eliminación que ocurren en las entidades, abriendo la puerta a sistemas de trazabilidad robustos. ¿Has implementado auditoría en tus proyectos? Comparte tu experiencia en los comentarios.