我正在使用hibernate 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;
}
}
每当关联两个对象时,例如对于@OneToOne
,对关系任何一方的更改都不会级联对该关系另一方的审核,除非您:
B
指向另一个A
实例从简单的变更数据捕获(CDC)角度来看,这些规则是有意义的。我的意思是在屏幕上未以任何有意义的方式修改的关联实体上的属性不能证明审计行的合理性,因此我们只捕获实际检测到任何更改的一侧的实体实例。
在复杂的域模型中,我们在对象之间存在大量关系。想象一下,如果我们跨越关系边界传播这些更改事件,则会生成大量的审计行。您可能很容易遇到更改基本字符串属性会导致审核与更改实体相关的实体的整个对象图的情况。
你有几种方法可以完成你想要的任务:
有条件审计的文档中有一整节。其最初目的是控制审计实体的某些变更是否应允许记录实体,但您也可以使用它来导航非常具体的相关实体并强制对相关实体进行工作单位审计操作。这是一种专家方法,而不是我建议不熟悉的用户及其运作方式。在6.0中,我希望在某些方面简化这一过程,以减少用户当前必须执行的操作。
最简单的方法是做(2)。为此,您可以在两个实体上添加一个新字段,用于存储诸如时间戳值之类的内容。每当UI中的任一实体发生更改时,您都会为两个实体设置时间戳,这将有效地强制Envers审核同一事务中的两个实体,从而精确地完成您想要的任务。
这是用户经常提出的,所以我创建了HHH-13362,我们可以在这里更详细地讨论如何以较少侵入的方式最好地开发和改进。