Hi,
Currently I'm playing with entity listener to implement auditing with difference between values in updated entity. There is a problem however with accessing "old" version of object stored in database. I can't find the nice way to use EntityManager in EntityListener. Because of that, I can't store separate entity for given event. Right now I'm using BaseEntity which contains
@ElementCollection private Set<ActivityLog> activities;
This way I can add events to given object without using EM to persist new object.
What I want to accomplish is to log difference between new and old values for every change in database.
This is example how this can be done with hibernate:
@Override public final boolean onPreUpdate(PreUpdateEvent event) { try { // TODO : need to get the actor ID somehow final Long actorId = 0L; final Serializable entityId = event.getPersister().hasIdentifierProperty() ? event.getPersister().getIdentifier(event.getEntity(), event.getPersister().guessEntityMode(event.getEntity())) : null; final String entityName = event.getEntity().getClass().toString(); final Date transTime = new Date(); // new Date(event.getSource().getTimestamp()); final EntityMode entityMode = event.getPersister().guessEntityMode(event.getEntity()); Object oldPropValue = null; Object newPropValue = null; // need to have a separate session for audit save StatelessSession session = event.getPersister().getFactory().openStatelessSession(); session.beginTransaction(); // get the existing entity from session so that we can extract existing property values Object existingEntity = session.get(event.getEntity().getClass(), entityId); // cycle through property names, extract corresponding property values and insert new entry in audit trail for (String propertyName : event.getPersister().getPropertyNames()) { newPropValue = event.getPersister().getPropertyValue(event.getEntity(), propertyName, entityMode); // because we are performing an insert we only need to be concerned will non-null values if (newPropValue != null) { // collections will fire their own events if (!(newPropValue instanceof Collection)) { oldPropValue = event.getPersister().getPropertyValue(existingEntity, propertyName, entityMode); if (LOG.isDebugEnabled()) { LOG.debug("{} for: {}, ID: {}, property: {}, old value: {}, new value: {}, actor: {}, date: {}", new Object[] { OPERATION_TYPE_UPDATE, entityName, entityId, propertyName, oldPropValue, newPropValue, actorId, transTime }); } session.insert(new AuditTrail(entityId.toString(), entityName, propertyName, oldPropValue != null ? oldPropValue.toString() : null, newPropValue != null ? newPropValue .toString() : null, OPERATION_TYPE_UPDATE, actorId, transTime)); } } } session.getTransaction().commit(); session.close();
It's only a small part of the code. So, is it somehow possible to implement something similar in ODB? Or is there any way to implement this in current version of ODB?