I want to do Audit for my entity updates. So I have implemented EmptyInterceptor.
My onFlushDirty()
method is not executing, but afterTransactionCompletion()
does executes
I'm using Spring 4.1 and Hibernate 5.0
+
I have not done any configuration rather than @Component
in configuration file till afterTransactionCompletion()
get executed.
What I'm missing here ?
Also how to intercept Event query.executeUpdate()
?
My Interceptor class is as follows:
@Component
public class AuditLogInterceptor extends EmptyInterceptor {
private static final long serialVersionUID = 1L;
@Override
public boolean onFlushDirty(Object entity, Serializable id,
Object[] currentState, Object[] previousState,
String[] propertyNames, Type[] types) {
System.out.println("AuditLogInterceptor.onFlushDirty()");
System.out.println();
System.out.println("Property Names :- ");
for (String propertyName : propertyNames) {
System.out.print(", "+propertyName);
}
System.out.println();
System.out.println("Current State :- ");
for (Object current : currentState) {
System.out.print(", "+ String.valueOf( current ) );
}
System.out.println();
System.out.println("Previous State :- ");
for (Object previous : previousState) {
System.out.print(", "+ String.valueOf( previous ) );
}
return true;
//return super.onFlushDirty(entity, id, currentState, previousState,
//propertyNames, types);
}
@Override
public void afterTransactionCompletion(Transaction tx) {
// TODO Auto-generated method stub
System.out.println("AuditLogInterceptor.afterTransactionCompletion()");
super.afterTransactionCompletion(tx);
}
@Override
public boolean onSave(Object entity, Serializable id, Object[] state,
String[] propertyNames, Type[] types) {
System.out.println("AuditLogInterceptor.onSave()");
System.out.println("Property Names :- "+Arrays.toString(propertyNames));
System.out.println("States :- "+Arrays.toString(state));
return super.onSave(entity, id, state, propertyNames, types);
}
@Override
public void postFlush(@SuppressWarnings("rawtypes") Iterator entities) {
System.out.println();
System.out.println("AuditLogInterceptor.postFlush()");
for ( ; entities.hasNext() ;) {
System.out.println("-----"+ entities.next().getClass().getSimpleName());
}
System.out.println();
super.postFlush(entities);
}
}
Code In my DAO
@Override
public boolean updateAssignment( Integer workTaskDetailId, short workTaskStatus ) {
Session session = null;
Transaction transaction = null;
boolean isUpdated = false;
try {
session = this.sessionFactory.withOptions().interceptor( new AuditLogInterceptor() ).openSession();
transaction = session.beginTransaction();
String COMPLETION_DATE = "";
if( workTaskStatus == 263 )
COMPLETION_DATE = ", wtd.completionDate = :completionDate ";
final String UPDATE_WORKTASKSTATUS = "update WorkTaskDetail wtd set wtd.workTaskStatus = :workTaskStatus "
+COMPLETION_DATE+ "where wtd.workTaskDetailId = :workTaskDetailId ";
Query query = session.createQuery(UPDATE_WORKTASKSTATUS).setShort("workTaskStatus", workTaskStatus)
.setInteger("workTaskDetailId", workTaskDetailId);
if( workTaskStatus == 263 )
query.setDate("completionDate", new Date() );
int updateCount = query.executeUpdate();
if( updateCount > 0 )
isUpdated = true;
if( session != null )
session.flush();
if( transaction != null && transaction.getStatus().equals(TransactionStatus.ACTIVE) )
transaction.commit();
} catch ( Exception exception ) {
if( transaction != null && transaction.getStatus().equals( TransactionStatus.ACTIVE) )
transaction.rollback();
LOGGER.error("Message :- "+exception.getMessage());
LOGGER.error("Root Cause :- "+exception.getCause());
LOGGER.error(" ************************************************************");
} finally {
if( session != null )
session.close();
}
return isUpdated;
}
The onFlushDirty
method was not called because there was no entity being modified by the currently running Persistence Context.
Only managed entities can generate automatic UPDATE statements. In your case, you are executing a manual SQL UPDATE, which is beyond the scope of Hibernate entity state transitions.
Therefore, you have two choices: