据我所知,Hibernate Envers在创建,更改或删除带有@Audited注释的对象时存储修订。
Envers自动将修订日期设置为当前时间。可以手动设置该时间吗?
我需要使用它来处理时间收集,其中数据具有有效时间,需要手动设置。
答案 0 :(得分:1)
可以,但是乍一看似乎并不直观。
当Envers创建其修订实体实例时,会发生几件事。
@RevisionTimestamp
注释的属性是使用当前时间设置的。RevisionListener
被调用并提供了修订实体实例。您可以通过两种方式指定RevisionListener
,这实际上取决于您当前是否提供自定义修订实体实例或使用Envers根据您的设置解析的实例。
在这种情况下,您可以通过在实体类的RevisionListener
类注释上设置@RevisionEntity
来指定它。
@RevisionEntity(YourCustomRevisionListener.class)
public class CustomRevisionEntity {
...
}
在这种情况下,您需要通过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解析值,则需要确定以下哪一项适用于您:
在这种情况下,您将必须使用ThreadLocal变量的旧方法来传递应用程序作用域实例/值以访问侦听器内部的实例/值。
在这种情况下,由于我们添加了在创建侦听器实例时自动解析CDI bean的支持,因此可以使用CDI注入简单地注入CDI bean。
您可以使用Spring的注入注释将Spring bean直接注入到侦听器中,就像侦听器是spring-bean一样。
在这种情况下,您将需要使用ThreadLocal变量的传统方法,因为Spring Framework直到5.1才添加对将bean注入Hibernate bean的支持。