Spring Envers 条件更新

Spring Envers conditional update

我正在使用 Spring 启动与 Spring 数据和 Hibernate 5 Envers。 它工作正常。我不想忽略基于字段内容的更新(例如状态)。我遵循了这个 guide 和 hibernate 的官方文档。但是,当我尝试实现 EnversPreUpdateEventListenerImpl 时,找不到它。我在我的 pom 中包含了 envers:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-envers</artifactId>
</dependency>

我有 EnversPreCollectionUpdateEventListenerImpl 和类似的 类 可用,这让我觉得我的方法是错误的。有人有什么建议吗?

这里的第一步是确定您需要覆盖哪些侦听器。从你的问题听起来你已经确定了。

我推荐的第一件事是为 Hibernate 提供 hibernate.envers.autoRegisterListeners 配置 属性 设置为 false。这确保在调用默认 EnversIntegrator 时,它会跳过事件注册,防止默认侦听器附加到 SessionFactory.

下一步基本上是 复制 org.hibernate.envers.boot.internal.EnversIntegrator 代码到自定义 class。您显然可以排除侦听器选择退出检查,因为您的自定义实现不需要该检查。您需要更改的是注册侦听器的几行,而不是注册您自己的而不是默认的。

例如

if ( enversService.getEntityConfigurations().hasAuditedEntities() ) {
  // ...
  listenerRegistry.appendListeners( 
    EventType.PRE_UPDATE, 
    new MyCustomEnversPreUpdateEventListener( enversService )
  );
}

其中 MyCustomEnversPreUpdateEventListener 看起来像这样

public class MyCustomEnversPreUpdateEventListener 
  extends EnversPreUpdateEventListenerImpl {
  @Override
  public void onPreUpdate(PreUpdateEvent event) {
    final String entityName = event.getPersister().getEntityName();
    if ( getEnversService().getEntitiesConfigurations().isVersioned( entityName ) ) {
        checkIfTransactionInProgress( event.getSession() );
        if ( yourFieldStatusMatchesAuditCriteria( event ) ) {
          return super.onPreUpdate( event );
        }
    }
    return false;
  }
}

如果您可以找到所有其他侦听器 classes 但找不到 pre-update 处理程序,则可能您使用的是旧版本的 Envers。值得注意的是,最近在 Hibernate Envers 中添加了 pre-update 事件监听器,确切地说是版本 5.2.7。