Hibernate Envers自定义字段供用户输入 [英] Hibernate Envers custom field for user input

查看:123
本文介绍了Hibernate Envers自定义字段供用户输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有自定义RevisionEntityRevisionListener的Spring Boot和Hibernate Envers将其他信息(如用户名,ip)存储在修订信息中.效果很好.

I'm using Spring Boot and Hibernate Envers with a custom RevisionEntity and RevisionListener to store additional information like username, ip in the revision info. It works fine.

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

As a new requirement I also need to store modification comment from the user. So if a user changes an entity he/she also needs to enter a reason for this change. This text should be saved among the other revision information.

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

I have the text in my Controller and in the Service class as well, but how can I populate the RevisionListener with this information?

推荐答案

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

The ideal answer to your question depends on the versions of both Hibernate and Spring Framework that you are currently using as some new features added in the later versions of both making injecting application state into the RevisionListener callback tremendously easier to obtain.

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

If you are using Hibernate 5.2 or prior, you're going to be restricted to the legacy approach of injecting the application state using ThreadLocal variables. In a web application, this can easily be done either by setting up a web filter or doing this as a part of your web controller.

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

The goal is to initialize the ThreadLocal prior to calling whatever business service/bean that performs the persistence operation and clearing the state after the persistence operation has been committed. Since most spring-based applications tend to wrap the service method in a @Transactional annotation then handling the initialization and clearing of the ThreadLocal in the controller seems logical.

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

Since the ThreadLocal is a global variable that is scoped to the executing thread, the listener will be able to ask the thread local instance for the value in order to set it on the custom revision entity. The most important thing is to set it before the persistence operation starts and to clear it after its saved.

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

This likely doesn't apply to you since you're in a Spring environment, but for the sake of completeness of all the possible configuration choices, I'm including it.

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

If you are using Hibernate 5.3 or later in a CDI-based environment, Hibernate added default support for CDI injection, basically allowing certain objects created by Hibernate to actually become CDI beans and support having state injected into them. In other words

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时,必须将旧方法与ThreadLocal结合使用变量.

Using Hibernate 5.3+ but with Spring 5.0 or prior

In order to get Spring Framework bean injection to work, you must be using Spring Framework 5.1 or later where they added that support, otherwise when using Spring Framework 5.0 or prior with Hibernate, you must use the legacy approach with ThreadLocal variables.

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

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

If you are using Hibernate 5.3 or later with Spring Framework 5.1 or later, then you're in luck. In this use case, you can mimic the default CDI support automatically because Spring Framework 5.1 provides their own bean registry implementation and wires it automatically into Hibernate's framework. In short, this means that you can easily auto-wire Spring beans into the RevisionListener just as if you were using CDI.

public class CustomRevisionListener implements RevisionListener {
  @Autowired
  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 Envers自定义字段供用户输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆