Auditar cambios usando Hibernate Envers

A partir de v5.9 también puedes usar el nuevo AccessTracker de OpenXava

Agregar en persistence.xml:
<properties>
...
    <property name="hibernate.hbm2ddl.auto" value="update"/>
...
    <property name="org.hibernate.envers.audit_strategy"
         value="org.hibernate.envers.strategy.ValidityAuditStrategy"/>
    <property name="org.hibernate.envers.audit_strategy_validity_store_revend_timestamp"
         value="true"/>
...
</properties>
Es posible configurar varios aspectos del compartamiento de Hibernate Envers, revisa la documentación al respecto.
A partir de la v5.4 se ha añadido la API de Hibernate Envers por defecto. Para las versiones 5.3.* es necesario incluir la API en el classpath. La v5.3 presentaba un bug que se resuelve en en esta discusión.

Hasta la version 5.2.1

Agregar en persistence.xml:
<properties>
...
    <property name="hibernate.ejb.event.post-insert"
        value="org.hibernate.ejb.event.EJB3PostInsertEventListener,org.hibernate.envers.event.AuditEventListener" />
    <property name="hibernate.ejb.event.post-update"
        value="org.hibernate.ejb.event.EJB3PostUpdateEventListener,org.hibernate.envers.event.AuditEventListener" />
    <property name="hibernate.ejb.event.post-delete"
        value="org.hibernate.ejb.event.EJB3PostDeleteEventListener,org.hibernate.envers.event.AuditEventListener" />
    <property name="hibernate.ejb.event.pre-collection-update"
        value="org.hibernate.envers.event.AuditEventListener" />
    <property name="hibernate.ejb.event.pre-collection-remove"
        value="org.hibernate.envers.event.AuditEventListener" />
    <property name="hibernate.ejb.event.post-collection-recreate"
        value="org.hibernate.envers.event.AuditEventListener" />
...
</properties>
En el build.xml del proyecto OpenXava modificar en hibernatetool el classname agregando Envers. Debe quedar así:
<taskdef name="hibernatetool"
  classname="org.hibernate.tool.ant.EnversHibernateToolTask"
  classpathref="jpatoolslib"/>
Crear la clase RevEntidad parar indicar que la revisión tendrá también usuario
package org.openxava.tuproyecto.auditoria;
 
import javax.persistence.*;
import org.hibernate.envers.RevisionEntity;
import org.hibernate.envers.DefaultRevisionEntity;
 
@Entity
@RevisionEntity(ListenerUsuario.class)
public class RevEntidad extends DefaultRevisionEntity{
 
  private String username;
  public String getUsername() { return username; }
  public void setUsername(String username) { this.username = username; }
 
}
Crear la clase ListenerUsuario para capturar el usuario que está haciendo la modificación.
package org.openxava.tuproyecto.auditoria;
 
import org.hibernate.envers.*;
import org.openxava.util.*;
 
public class ListenerUsuario implements RevisionListener{
 
    public void newRevision(Object revisionEntity) {
        RevEntidad reventidad = (RevEntidad) revisionEntity;
        reventidad.setUsername(getUsuarioActual());
    }
 
    public static String getUsuarioActual() {
        if (Users.getCurrent() != null) {
            return Users.getCurrentUserInfo().getGivenName() + " " +
                Users.getCurrentUserInfo().getFamilyName();
        } else {
            return "";
        }
    }
}
 
Finalmente agregar a la clase que se desea auditar: @Audited

Generar la base de datos y desplegar la aplicación.