如何通过双向的休眠模式审计一对一关系?

时间:2019-04-03 12:27:26

标签: java hibernate hibernate-envers

我正在使用休眠Envers进行审核。

我有两个实体类,A和B。它们之间存在一对一的关系。 因此,这将创建两个审核表A_aud和B_aud。 两者的创建/更新都是通过一个屏幕完成的。

因此,我的要求是,只要这两个表的任何表(在它们的任何字段中)都发生变化,我都需要在两个表中进行审核。

我该如何实现?

这就是我在两侧定义映射的方式

    public class A implements Serializable {
           private B b;

           @OneToOne(mappedBy = "a", cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false)
           public B getB() {
             return b;
           }

           public void setB(B b) {
             this.b = b;
           }
}

public class B implements Serializable{
    private A a;

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "A_ID", referencedColumnName = "id",nullable = false)
    public A getA() {
        return a;
    }

    public void setA(A a) {
        this.a = a;
    }
}

1 个答案:

答案 0 :(得分:0)

每当两个对象相关联时(例如与您的@OneToOne关联),除非您执行以下操作,否则对关系的任一侧所做的更改都不会级联对该关系另一侧的审核:

  1. 修改关系,例如将B指向A的另一个实例
  2. 修改关系另一侧的属性

从简单的变更数据捕获(CDC)角度来看,这些规则是有意义的。我的意思是,在您的屏幕上未以任何有意义的方式修改的关联实体上的属性不能证明审计行是合理的,因此我们仅捕获实际上已检测到任何更改的那一侧的实体实例。

在复杂的领域模型中,我们在对象之间具有多种关系。试想一下,如果我们跨关系边界传播那些变更事件,那么将会生成大量的审计行。您很容易遇到这样的情况:基本字符串属性的更改将导致审核与更改后的实体相关的实体的整个对象图。

您可以通过两种方式完成自己想要的事情:

  1. 使用条件审计
  2. 使用属性强制进行审核。

条件审计文档中有一整节内容。其最初的目的是控制审核实体上的某些更改是否应允许记录实体,但您也可以使用它来导航非常相关的特定实体,并对相关实体强制执行工作单位审核操作。这是一种专家方法,我不建议不熟悉它的用户及其操作方式。在6.0中,我希望以某种方式简化此操作,以使其比用户当前必须的操作更具侵入性。

最简单的方法是执行(2)。为此,您将在两个实体上添加一个新字段,该字段将存储诸如时间戳记值之类的内容。每当您的UI中的任何一个实体发生更改时,您都将为这两个实体设置时间戳,这将有效地迫使Envers审核同一事务中的两个实体,从而精确地完成您想要的工作。

这是用户经常提出的问题,因此我创建了HHH-13362,在这里我们可以更详细地讨论如何以一种不太干扰的方式最好地开发和改进它。