Hibernate Envers自定义字段供用户输入

时间:2019-05-08 11:43:44

标签: hibernate spring-boot hibernate-envers

我正在将Spring Boot和Hibernate Envers与自定义RevisionEntityRevisionListener一起使用,以在修订信息中存储其他信息,例如用户名,ip。很好。

作为一项新要求,我还需要存储用户的修改评论。因此,如果用户更改实体,则他/她还需要输入进行更改的原因。该文本应保存在其他修订信息中。

我在ControllerService类中也都有文本,但是如何用此信息填充RevisionListener

1 个答案:

答案 0 :(得分:1)

问题的理想答案取决于您当前正在使用的Hibernate和Spring Framework的版本,因为它们在以后的版本中都添加了一些新功能,这使得将应用程序状态注入到RevisionListener回调中非常容易获取。

使用Hibernate 5.2或更早版本

如果您使用的是Hibernate 5.2或更早版本,则将限于使用ThreadLocal变量注入应用程序状态的传统方法。在Web应用程序中,可以通过设置Web过滤器或将其作为Web控制器的一部分轻松地完成此操作。

目标是在调用执行持久性操作的任何业务服务/ bean之前初始化ThreadLocal,并在提交持久性操作后清除状态。由于大多数基于Spring的应用程序倾向于将服务方法包装在@Transactional批注中,因此在控制器中处理ThreadLocal的初始化和清除似乎是合乎逻辑的。

由于ThreadLocal是作用于执行线程的全局变量,因此侦听器将能够向线程本地实例询问该值,以便在自定义修订版实体上进行设置。最重要的是在持久性操作开始之前进行设置,并在保存之后清除它。

在CDI环境中使用Hibernate 5.3 +

这可能不适用于您,因为您处于Spring环境中,但为了所有可能的配置选择的完整性,我将其包括在内。

如果您在基于CDI的环境中使用Hibernate 5.3或更高版本,则Hibernate添加了对CDI注入的默认支持,基本上允许Hibernate创建的某些对象实际上成为CDI Bean,并支持将状态注入其中。换句话说

public class CustomRevisionListener implements RevisionListener {
  @Inject
  private UserReasonBean reasonBean;

  @Override
  public void newRevision(Object revisionEntity) {
    // inside this method, you can get the reason from the injected reasonBean
    // and now set the reason on the custom revision entity instance.
  }
}

使用Hibernate 5.3+,但使用Spring 5.0或更低版本

为了使Spring Framework Bean注入正常工作,您必须使用Spring Framework 5.1或更高版本并在其中添加了该支持,否则,在使用Spring Framework 5.0或更低版本的Hibernate时,必须将旧方法与{{1 }}变量。

请参见使用Hibernate 5.2或更早版本

在Spring 5.1+中使用Hibernate 5.3 +

如果您将Hibernate 5.3或更高版本与Spring Framework 5.1或更高版本配合使用,那么您很幸运。在这种情况下,您可以自动模仿默认的CDI支持,因为Spring Framework 5.1提供了自己的bean注册表实现,并将其自动连接到Hibernate的框架中。简而言之,这意味着您可以像使用CDI一样轻松地将Spring bean自动连线到ThreadLocal中。

RevisionListener