我正在将Spring Boot和Hibernate Envers与自定义RevisionEntity
和RevisionListener
一起使用,以在修订信息中存储其他信息,例如用户名,ip。很好。
作为一项新要求,我还需要存储用户的修改评论。因此,如果用户更改实体,则他/她还需要输入进行更改的原因。该文本应保存在其他修订信息中。
我在Controller
和Service
类中也都有文本,但是如何用此信息填充RevisionListener
?
答案 0 :(得分:1)
问题的理想答案取决于您当前正在使用的Hibernate和Spring Framework的版本,因为它们在以后的版本中都添加了一些新功能,这使得将应用程序状态注入到RevisionListener
回调中非常容易获取。
如果您使用的是Hibernate 5.2或更早版本,则将限于使用ThreadLocal
变量注入应用程序状态的传统方法。在Web应用程序中,可以通过设置Web过滤器或将其作为Web控制器的一部分轻松地完成此操作。
目标是在调用执行持久性操作的任何业务服务/ bean之前初始化ThreadLocal
,并在提交持久性操作后清除状态。由于大多数基于Spring的应用程序倾向于将服务方法包装在@Transactional
批注中,因此在控制器中处理ThreadLocal
的初始化和清除似乎是合乎逻辑的。
由于ThreadLocal
是作用于执行线程的全局变量,因此侦听器将能够向线程本地实例询问该值,以便在自定义修订版实体上进行设置。最重要的是在持久性操作开始之前进行设置,并在保存之后清除它。
这可能不适用于您,因为您处于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.
}
}
为了使Spring Framework Bean注入正常工作,您必须使用Spring Framework 5.1或更高版本并在其中添加了该支持,否则,在使用Spring Framework 5.0或更低版本的Hibernate时,必须将旧方法与{{1 }}变量。
请参见使用Hibernate 5.2或更早版本
如果您将Hibernate 5.3或更高版本与Spring Framework 5.1或更高版本配合使用,那么您很幸运。在这种情况下,您可以自动模仿默认的CDI支持,因为Spring Framework 5.1提供了自己的bean注册表实现,并将其自动连接到Hibernate的框架中。简而言之,这意味着您可以像使用CDI一样轻松地将Spring bean自动连线到ThreadLocal
中。
RevisionListener