2017-08-09 18 views
1

我想爲我的實體更新執行審計。所以我實施了EmptyInterceptor
onFlushDirty()法不執行,但afterTransactionCompletion()確實執行Hibernate EmptyInterceptor onFlushDirty()未執行

我使用Spring 4.1和Hibernate 5.0
+
我沒有做任何配置,而不是@Component在配置文件中,直到afterTransactionCompletion()得到執行。

我在這裏錯過了什麼?
另外如何攔截事件query.executeUpdate()

我的攔截器類如下:

@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); 
    } 
} 

代碼在我的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; 
} 

回答

1

因爲得到了由當前正在運行的持久化上下文被修改沒有實體的onFlushDirty方法不叫。

正如我explained in this article,只有管理實體可以生成自動UPDATE語句。在你的情況下,你正在執行一個手動SQL UPDATE,這超出了Hibernate entity state transitions的範圍。

因此,你有兩個選擇:

  1. 使用Hibernate Envers,因爲沒有必要寫在休眠的頂自制的審計日誌。
  2. 使用Debezium,因爲無論如何,DB已經具有審計日誌(又名WAL,重做日誌,事務日誌)。
+0

如何審計刪除記錄.in插入和更新我們可以使用創建和更新的用戶,但在刪除我們不知道誰刪除記錄 –