Hibernate envers 如何将字段添加到审计 table

Hibernate envers how to add fields to audit table

我想要的是将@ModifiedBy@LastModifiedDate@CreatedByCreatedDate保存到所有审计表中。使它变得困难的是我不想在我的 @Entity POJO 中包含这些字段。如果可能的话,如何做到这一点?

是的,但实现方式与您所说的略有不同。

在实际审计行本身引入这些东西的问题是你 运行 可能有大量非规范化数据分散在审计模式中的风险,尤其是当你考虑这样一个事实时审计修订可以包含多个实体。

Envers 完成您所描述的方法是分别处理各个部分。

为了捕获执行审计操作的人员,最好的方法是扩展或提供您自己的修订实体实现。在此实体中,您将包含一个列,用于存储用户名或您想要的任何用户标识值。

为了填充该实体中的用户名或标识值,您还需要编写自定义 RevisionListener 并在修订实体的 @RevisionEntity 注释中指定它。您可以在用户文档 here.

中找到示例

为了获得修订的时间戳,您不仅需要获取实体,还需要获取该审计行的修订实体。这样一来,您不仅可以获得修订发生的时间戳、进行更改的自定义字段,还可以获得修订类型 (ADD,MOD,DEL),这样您就可以确定是否您正在阅读的值是 CreationModification 角色。

据我了解你的问题,你只是不想在你的 POJO class 中创建这些字段,所以你可以创建一个 @MappedSuperclass 包含与审计相关的字段,您可以稍后将其扩展到所有实体 classes。 在这里,例如,我正在创建一个名为 Auditable 的抽象 class,它将扩展到所有实体 classes.

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
abstract class Auditable<User> {


@CreatedBy
@Column(nullable = false, updatable = false)
private String createdBy;

@CreatedDate
@Column(nullable = false, updatable = false)
private LocalDateTime created;

@LastModifiedBy
@Column(nullable = false)
private String modifiedBy;

@LastModifiedDate
@Column(nullable = false)
private LocalDateTime modified;



@Column(nullable = false)
@NotBlank(message = "username is required")
private String username;


public String getUsername() {
    return username;
}

public void setUsername(String username) {
    this.username = username;
}

public LocalDateTime getCreated() {
    return created;
}

public LocalDateTime getModified() {
    return modified;
}

public String getCreatedBy() {
    return createdBy;
}

public String getModifiedBy() {
    return modifiedBy;
}
}

在此之后,您可以在所有实体 classes 中轻松使用它,因为这是一个超级class,您可以在所有实体中使用它。例如,我正在创建一个名为 Employee 的实体,我希望在其中设置可审计字段

@Entity
@Table
@EntityListeners(AuditingEntityListener.class)
public class Employee extends Auditable<String>{

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id ;

@Column(nullable = false)
private String empName ;

@Column(nullable = false)
private String department ;

@Column(nullable = false)
private Integer age ;




public Integer getAge() {
    return age;
}

public void setAge(Integer age) {
    this.age = age;
}

public String getDepartment() {
    return department;
}

public void setDepartment(String department) {
    this.department = department;
}

public String getEmpName() {
    return empName;
}

public void setEmpName(String empName) {
    this.empName = empName;
}

public Integer getId() {
    return id;
}

public void setId(Integer id) {
    this.id = id;
}
}