Hibernate - 跳过特定操作或事务的历史记录

Hibernate - Skip Envers historisation for specific action or a transaction

我们目前正在使用 Envers 进行历史化。有时我们必须创建某些数据的临时副本,或者只是不想让某些事情成为历史。目前,我们有一个非常丑陋的解决方案。该解决方案是一个全局布尔值,它不能保证线程安全,并且可能导致某些应该被历史化的数据没有被历史化,或者相反。

我想知道有没有什么好的解决办法。我假设一种方法可能是使用 EnversPost*EventListeners 并标记每个应该被忽略一次的 bean。然而,虽然这听起来不那么可怕,但我担心它可能仍然不会很好地结束,因为我不太确定 Hibernate 中的对象生命周期是什么样的以及这是否会导致假阴性。

无论如何,对我来说似乎应该有一些更好的内置解决方案来解决这个问题,但我找不到任何东西。

听起来你所描述的是所谓的条件审计。

目前执行此操作的唯一方法是扩展现有的 Hibernate Envers 侦听器并在需要跳过基于实体当前状态创建审计实体行的地方添加任何逻辑。您会在 org.hibernate.envers.event.spi 中找到相当多的侦听器,涵盖所有必要的生命周期回调,不仅适用于实体,还适用于与实体关联的集合。

总的来说,post 事件在这里很重要。有一些 pre-collectionpre-update 事件监听器,但唯一可能需要扩展的可能是与集合相关的监听器,具体取决于您使用的实体映射。

扩展必要的侦听器后,您需要通过设置 hibernate.envers.autoRegisterListeners=false.

将 Envers 配置为不注册自己的侦听器

您还需要引入自定义 Integrator 实现来执行扩展侦听器的注册。您可以查看 org.hibernate.envers.EnversIntegrator 中的代码,了解有关如何执行此操作的所有相关详细信息。这些集成器是使用 Java 服务 API 检测到的,因此您还需要将一个 META-INF/services/org.hibernate.integrator.spi.Integrator 文件添加到您的类路径中,其中列出了您的自定义集成器,以便可以找到它。