用于用户输入的 Hibernate Envers 自定义字段
Hibernate Envers custom field for user input
我正在使用 Spring Boot 和 Hibernate Envers 以及自定义 RevisionEntity
和 RevisionListener
来存储附加信息,例如修订信息中的用户名、ip。效果很好。
作为新需求,我还需要存储用户的修改评论。因此,如果用户更改实体 he/she 还需要输入此更改的原因。此文本应与其他修订信息一起保存。
我的 Controller
和 Service
class 中都有文本,但是如何用这些信息填充 RevisionListener
?
您问题的理想答案取决于您当前使用的 Hibernate 和 Spring Framework 的版本,因为在这两个版本的更高版本中添加了一些新功能,将应用程序状态注入 RevisionListener
回调非常容易获得。
使用 Hibernate 5.2 或更早版本
如果您使用的是 Hibernate 5.2 或更早版本,您将只能使用使用 ThreadLocal
变量注入应用程序状态的传统方法。在 Web 应用程序中,这可以通过设置 Web 过滤器或作为 Web 控制器的一部分来轻松完成。
目标是在调用执行持久化操作的任何业务 service/bean 之前初始化 ThreadLocal
并在提交持久化操作后清除状态。由于大多数 spring-based 应用程序倾向于将服务方法包装在 @Transactional
注释中,然后在控制器中处理 ThreadLocal
的初始化和清除似乎是合乎逻辑的。
由于 ThreadLocal
是作用域为执行线程的全局变量,侦听器将能够向线程本地实例询问值,以便在自定义修订实体上设置它。最重要的是在持久化操作开始前设置,保存后清除。
在 CDI 环境中使用 Hibernate 5.3+
这可能不适用于您,因为您处于 Spring 环境中,但为了所有可能的配置选择的完整性,我将其包括在内。
如果您在 CDI-based 环境中使用 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 之前,您必须使用带有 ThreadLocal
变量的传统方法。
请参阅使用 Hibernate 5.2 或更早版本
将 Hibernate 5.3+ 与 Spring 5.1+
一起使用
如果您将 Hibernate 5.3 或更高版本与 Spring Framework 5.1 或更高版本一起使用,那么您很幸运。在此用例中,您可以自动模仿默认的 CDI 支持,因为 Spring Framework 5.1 提供了他们自己的 bean 注册表实现并将其自动连接到 Hibernate 的框架中。简而言之,这意味着您可以轻松地将 auto-wire Spring bean 放入 RevisionListener
中,就像您使用 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.
}
}
我正在使用 Spring Boot 和 Hibernate Envers 以及自定义 RevisionEntity
和 RevisionListener
来存储附加信息,例如修订信息中的用户名、ip。效果很好。
作为新需求,我还需要存储用户的修改评论。因此,如果用户更改实体 he/she 还需要输入此更改的原因。此文本应与其他修订信息一起保存。
我的 Controller
和 Service
class 中都有文本,但是如何用这些信息填充 RevisionListener
?
您问题的理想答案取决于您当前使用的 Hibernate 和 Spring Framework 的版本,因为在这两个版本的更高版本中添加了一些新功能,将应用程序状态注入 RevisionListener
回调非常容易获得。
使用 Hibernate 5.2 或更早版本
如果您使用的是 Hibernate 5.2 或更早版本,您将只能使用使用 ThreadLocal
变量注入应用程序状态的传统方法。在 Web 应用程序中,这可以通过设置 Web 过滤器或作为 Web 控制器的一部分来轻松完成。
目标是在调用执行持久化操作的任何业务 service/bean 之前初始化 ThreadLocal
并在提交持久化操作后清除状态。由于大多数 spring-based 应用程序倾向于将服务方法包装在 @Transactional
注释中,然后在控制器中处理 ThreadLocal
的初始化和清除似乎是合乎逻辑的。
由于 ThreadLocal
是作用域为执行线程的全局变量,侦听器将能够向线程本地实例询问值,以便在自定义修订实体上设置它。最重要的是在持久化操作开始前设置,保存后清除。
在 CDI 环境中使用 Hibernate 5.3+
这可能不适用于您,因为您处于 Spring 环境中,但为了所有可能的配置选择的完整性,我将其包括在内。
如果您在 CDI-based 环境中使用 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 之前,您必须使用带有 ThreadLocal
变量的传统方法。
请参阅使用 Hibernate 5.2 或更早版本
将 Hibernate 5.3+ 与 Spring 5.1+
一起使用如果您将 Hibernate 5.3 或更高版本与 Spring Framework 5.1 或更高版本一起使用,那么您很幸运。在此用例中,您可以自动模仿默认的 CDI 支持,因为 Spring Framework 5.1 提供了他们自己的 bean 注册表实现并将其自动连接到 Hibernate 的框架中。简而言之,这意味着您可以轻松地将 auto-wire Spring bean 放入 RevisionListener
中,就像您使用 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.
}
}