我想要的是将@ModifiedBy
、@LastModifiedDate
、@CreatedBy
和CreatedDate
保存到所有审核表中。让它变得困难的是,我不想在我的@Entity
POJO中有这些字段。如果这是可能的,怎么能做到呢?
确实如此,但实现与您所说的略有不同。
在实际审计行中引入这些内容的问题是,您可能会面临大量非规范化数据分散在审计模式中的风险,尤其是当您考虑到一个审计修订可以包含多个实体的事实时。
Envers实现您所描述的目标的方法是分别处理各个部分。
为了捕获执行审核操作的人员,最好的方法是扩展或提供您自己的修订实体实现。在这个实体中,您将包含一个列,用于存储用户名或您想要的任何用户标识值。
为了在该实体中填充用户名或标识值,还需要编写一个自定义RevisionListener
,并在修订实体的@RevisionEntity
注释中指定。您可以在这里的用户文档中找到示例。
为了获得修订的时间戳,您不仅需要获取实体,还需要获取该审计行的修订实体。通过这样做,您不仅可以获得修订发生的时间戳、进行更改的自定义字段,还可以获得修订的类型(ADD、MOD、DEL(,这样您就可以判断您读取的值是创建还是修改角色。
据我所知,您只是不希望在POJO类中创建这些字段,所以您可以创建一个包含审核相关字段的@MappedSuperclass,稍后可以将其扩展到所有实体类。例如,在这里,我正在创建一个名为Auditable的抽象类,该类将扩展到所有实体类。
@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;
}
}
之后,您可以很容易地在所有实体类中使用它,因为这是一个超类,您可以在所有实体中使用它。例如,我正在创建一个名为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;
}
}