Eu estou tentando criar uma tabela de auditoria que termina procurando algo parecido com isso:
entidade, id, propriedade, oldValue, newValue, usuário, timestamp
usando o Hibernate EmptyInterceptor Espero que esta tabela tenha muitos IOs . Parece que previouseState no método onFlushDirty não está funcionando como eu esperava.
Como posso obter o valor antigo sem buscá-lo do database como mostrado aqui ?
Eu estava tentando seguir este post
public class AuditLogInterceptor extends EmptyInterceptor { private Set inserts = new HashSet(); private Set updates = new HashSet(); private Set deletes = new HashSet(); private Map oldies = new HashMap(); @Override public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException { if (entity instanceof Auditable) inserts.add((Auditable)entity); return false; } @Override public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) { if (entity instanceof Auditable) deletes.add((Auditable)entity); } @Override public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) throws CallbackException { if (entity instanceof Auditable) { try { // Use the id and class to get the pre-update state from the database Session tempSession = HibernateUtil.getSessionFactory().openSession(); Auditable old = (Auditable) tempSession.get(entity.getClass(), ((Auditable) entity).getId()); oldies.put(old.getId(), old); updates.add((Auditable)entity); } catch (Throwable e) { _log.error(e,e); } } return false; }
Existe uma maneira de obter o estado de pré-atualização sem uma ida e volta para o database?
Uma abordagem alternativa é armazenar o estado anterior na carga.
@Entity @Table(name='Foo') class Foo { @Transient private Foo previousState; @PostLoad private void setPreviousState(){ previousState = new Foo(); //copy the fields } public Foo getPreviousState(){ return previousState; } }