当前位置: 首页 > 知识库问答 >
问题:

Hibernate EmptyInterceptor onFlushDirty()未执行

郜杰
2023-03-14

我想对我的实体更新进行审核。所以我实现了EmptyInterceptor
MyonFlushDirty()方法未执行,但执行了afterTransactionCompletion()

我正在使用Spring 4.1和Hibernate 5.0

在执行PostTransactionCompletion()之前,除了配置文件中的@Component之外,我没有做任何配置

我错过了什么?
如何拦截事件query.executeUpdate()

我的Interceptor类如下:

@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个答案

壤驷瑾瑜
2023-03-14

未调用onFlushDirty方法,因为当前运行的持久性上下文未修改任何实体。

只有托管实体才能生成自动更新语句。在本例中,您正在执行手动SQL更新,这超出了Hibernate实体状态转换的范围。

因此,你有两个选择:

  1. 使用Hibernate Envers,因为不需要在Hibernate之上编写自制的审核日志。
  2. 使用Debezium,因为DB已经具有审计日志(又名。WAL,重做日志,事务日志)。
 类似资料:
  • 我有@test Annotaion的测试市场。但是当我运行测试用例时,它显示测试运行:0,失败:0,跳过:0我正在从Eclipse中运行测试用例。我已经在Eclipse中安装了testng插件。 @test中的属性是自定义的。 TestNG版本:6.8.0

  • 我有这个问题。我试图从另一个线程更新我的< code>TextView,但它不允许。 我尝试了一堆不同的解决方案,但没有一个似乎没有帮助。在我的同时循环代码中,一直在打印“开始新循环”,但它没有从该继续。 有人能帮我找出如何从另一个线程更新吗?

  • 问题内容: 我已经尝试了这两个代码,但是却没有执行,有人可以告诉我为什么吗? 提前致谢 问题答案: 试试这个代码: 它会在源元素的位置单击并按住,移至目标元素的位置,然后释放鼠标。 要么 它将单击并按住源元素的位置,移动给定的偏移量,然后释放鼠标。 要么 它将执行以上两个代码的操作。 我在Java上编写此代码。您可以转换为指定的语言。 从动作引用。

  • 我试图实现一个简单的Spring AOP(v4)示例,使用建议和一个原位切入点表达式,但是没有调用方面方法。我有所有必需的依赖关系(spring-aop、aopalliance和aspectweaver)。我做错了什么? 方面:

  • 我正试图把普罗米修斯加入我的Spring靴项目。我正在使用Spring Boot执行器来公开度量endpoint。我按照教程做了所有的事情,但我总是得到一个404错误。我还尝试了中给出的每一个解决方案: context.xml(外部属性):

  • Maven项目标志错误:未能执行goal org.springframework.boot:spring-boot-maven-plugin:2.1.3。release:repackage(repackage)on project pet-clinic-data:repackage of goal org.springframework.boot:spring-boot-maven-plugin: