envers ejemplo data auditingentitylistener auditable spring dependency-injection hibernate-envers

ejemplo - spring auditable entity



hibernate-envers RevisionListener integraciĆ³n de primavera como Spring Bean (1)

Necesito hacer un procesamiento de base de datos en el oyente de revisión de Hibernate-Envers. Para eso necesito las capacidades de inejction de Spring Framework. ¿Cómo se puede implementar esto? Aquí está el código que representa la necesidad pero CustomRevisionListener es creado por un constructor en código Envers. Spring solo tiene SecurityContextHolder como localizador de servicios estáticos. ¿Cómo inyectar otros frijoles?

@Service public class CustomRevisionListener implements EntityTrackingRevisionListener { @Resource private PersistenceManagerHibernate persistenceManagerHibernate; public void newRevision(Object revisionEntity) { CustomRevisionEntity revision = (CustomRevisionEntity) revisionEntity; revision.setUsername(getUsername()); } public String getUsername() { final SecurityContext context = SecurityContextHolder.getContext(); if (context != null) { if (context.getAuthentication() != null) { return context.getAuthentication().getName(); } else { return "anonymous"; } } return "anonymous"; } @Override public void entityChanged(@SuppressWarnings("rawtypes") Class entityClass, String entityName, Serializable entityId, RevisionType revisionType, Object revisionEntity) { CustomRevisionEntity revision = (CustomRevisionEntity) revisionEntity; revision.setEntityId(entityId.toString()); revision.setEntityName(entityName); revision.setRevisionType((int)revisionType.getRepresentation()); Auditable auditable = null; if (entityId instanceof Long) { auditable = persistenceManagerHibernate.findById(entityClass, (Long)entityId); } revision.setGroupName(auditable.getAuditGroupName()); revision.setGroupEntityId(auditable.getAuditGroupId()); } }


Como CustomRevisionListener es instanciado por un constructor en Envers, debe encontrar otra forma de recuperar un identificador a un bean gestionado Spring.

Puede crear una clase de utilidad para lograr esto:

/** * Utility class which provides lookup services for Spring managed beans from * within unmanaged beans. */ @Component public class ContextLookup implements ApplicationContextAware { private static ApplicationContext sApplicationContext; @Override public void setApplicationContext( ApplicationContext aApplicationContext ) throws BeansException { setContext( aApplicationContext ); } public static void setContext( ApplicationContext aApplicationContext ) { sApplicationContext = aApplicationContext; } protected static ApplicationContext getApplicationContext() { return sApplicationContext; } public static Object getBean( String aName ) { if ( sApplicationContext != null ) { return sApplicationContext.getBean( aName ); } return null; } public static <T> T getBean( Class<T> aClass ) { if ( sApplicationContext != null ) { return sApplicationContext.getBean( aClass ); } return null; } }

y en su CustomRevisionListener

public class CustomRevisionListener { public void myMethod() { .. // get a handle to your spring managed bean Foo foo = (Foo)ContextLookup.getBean( "mySpringManagedBean" ); .. } }