我们目前正在使用Envers进行历史化。有时,我们必须创建某些数据的临时副本,或者只是不希望某些事情出现在历史上。目前,我们有一个非常丑陋的解决方案。该解决方案是一个全局布尔值,它不能保证线程安全,并且可能导致某些本应被历史化的数据不被历史化或反之。
我想知道是否有什么好的解决方案。我认为一种方法可能是使用EnversPost*EventListener
并标记每个应被忽略一次的bean。但是,虽然这听起来不太可怕,但我担心它可能仍然无法很好地结束,因为我不确定Hibernate中的对象生命周期是什么样子以及这是否会导致假阴性。
无论如何,对我来说似乎应该有一些更好的内置解决方案来解决这个问题,但是我什么也找不到。
最佳答案
听起来您所描述的称为条件审核。
当前执行此操作的唯一方法是扩展现有的Hibernate Envers侦听器,并在需要跳过基于实体当前状态创建审核实体行的地方添加任何逻辑。您可以在org.hibernate.envers.event.spi
中找到许多侦听器,这些侦听器不仅涵盖实体而且还涵盖与实体关联的集合的所有必需的生命周期回调。
一般来说,post
事件在这里很重要。 pre-collection
和pre-update
事件侦听器很少,但可能需要扩展的唯一事件侦听器可能是与集合相关的侦听器,具体取决于所使用的实体映射。
扩展了必要的侦听器之后,您需要通过设置hibernate.envers.autoRegisterListeners=false
将Envers配置为不注册自己的侦听器。
您还需要引入一个自定义Integrator
实现,该实现执行扩展侦听器的注册。您可以在org.hibernate.envers.EnversIntegrator
中查看有关如何执行此操作的所有相关详细信息的代码。这些集成器是使用Java Service API检测到的,因此,您还需要在类路径中添加META-INF/services/org.hibernate.integrator.spi.Integrator
文件,该文件列出了您的自定义集成器,以便可以找到它。