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

时间:2019-04-26 16:07:30

标签: java hibernate hibernate-envers

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

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

我需要使用它来处理时间收集,其中数据具有有效时间,需要手动设置。

1 个答案:

答案 0 :(得分:1)

可以,但是乍一看似乎并不直观。

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

  1. 带有@RevisionTimestamp注释的属性是使用当前时间设置的。
  2. 可选的RevisionListener被调用并提供了修订实体实例。

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

提供自定义修订实体

在这种情况下,您可以通过在实体类的RevisionListener类注释上设置@RevisionEntity来指定它。

@RevisionEntity(YourCustomRevisionListener.class)
public class CustomRevisionEntity {
  ...
}

通过配置提供RevisionListener

在这种情况下,您需要通过hibernate.properties文件或在您显式设置hibernate配置属性的代码中为Hibernate添加附加的引导程序配置属性:

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解析值,则需要确定以下哪一项适用于您:

使用5.3之前的Hibernate Envers版本

在这种情况下,您将必须使用ThreadLocal变量的旧方法来传递应用程序作用域实例/值以访问侦听器内部的实例/值。

通过CDI使用Hibernate Envers 5.3或更高版本

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

在Spring 5.1+中使用Hibernate Envers 5.3或更高版本

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

在5.1之前的Spring中使用Hibernate Envers 5.3或更高版本

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