使用 Hibernate Envers 手动设置修订日期

Setting the revision date manually with Hibernate Envers

据我所知,Hibernate Envers 在您创建、更改或删除使用 @Audited 注释的对象时存储修订。

Envers 自动将修订日期设置为当前时间。这个时间可以手动设置吗?

我需要它来处理数据具有有效时间的临时集合,我需要手动设置它。

可以,但乍一看可能不直观。

当 Envers 创建其修订实体实例时,会发生几件事。

  1. 注解属性的@RevisionTimestamp设置为当前时间
  2. 调用可选的 RevisionListener 并提供修订实体实例。

您可以通过两种方式指定 RevisionListener,这实际上取决于您当前是否提供自定义修订实体实例或使用 Envers 根据您的设置解析的实例。

提供自定义修订实体

在这种情况下,您可以通过在实体 class.

@RevisionEntity class 注释上设置来指定 RevisionListener
@RevisionEntity(YourCustomRevisionListener.class)
public class CustomRevisionEntity {
  ...
}

通过配置提供 RevisionListener

在这种情况下,您需要为 Hibernate 添加额外的 bootstrap 配置 属性,可以通过您的 hibernate.properties 文件或在您显式设置休眠配置的代码中属性:

org.hibernate.envers.revision_listener=com.company.envers.YourCustomRevisionListener

无论您采用哪种方法,您都将实施侦听器的契约并根据您的应用程序需要的任何规则显式设置时间戳值:

public class YourCustomRevisionListener implements RevisionListener {
  @Override
  public void newRevision(Object revisionEntity) {
    // I am going to assume here you're using a custom revision entity.
    // If you are not, you'll need to cast it to the appropriate class implementation.
    final CustomRevisionEntity revisionEntityImpl = (CustomRevisionEntity) revisionEntity;
    revisionEntityImpl.setTimestamp( resolveValidTimestampValue() );
  }

  private long resolveValidTimestampValue() {
    // implement your logic here.
  }
}

这里有几个注意事项。如果您需要解析应用程序中某个 bean 的值 space,您需要确定以下哪一项适用于您:

使用 5.3 之前的 Hibernate Envers 版本

在这种情况下,您必须使用 ThreadLocal 变量的传统方法来传递应用程序范围 instances/values 以访问侦听器内部的变量。

将 Hibernate Envers 5.3 或更高版本与 CDI 结合使用

在这种情况下,您可以简单地使用 CDI 的注入来注入 CDI bean,因为我们在创建侦听器实例时添加了自动解析 CDI bean 的支持。

将 Hibernate Envers 5.3 或更高版本与 Spring 5.1+

一起使用

您可以使用 Spring 的注入注解将 spring bean 直接注入到监听器中,就像监听器是一个 spring-bean 一样。

使用 Hibernate Envers 5.3 或更高版本,Spring 早于 5.1

在这种情况下,您将需要使用 ThreadLocal 变量的传统方法,因为 Spring Framework 直到 5.1 才添加对将 bean 注入 Hibernate bean 的支持。