如何在 Spring Boot 中使用 Envers 在审计 table 中添加字段
How to add fields in audit table using Envers in Spring Boot
早上好,如何在审计中添加字段table?
我需要审计一些table,但我需要得到执行操作的用户。我将接受审计的实体是:
@Entity
@Table(name ="TableName")
@Audited
@AuditTable("TableNameAuditedLog")
public class MyEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "myId")
private Long id;
@Column(name = "myName")
private String name;
}
查看文档,我看到了一个自定义示例 class 作为我的审计和侦听器,所以我这样做了:
@Data
@RevisionEntity(AuditListener.class)
@MappedSuperclass
public class Audit {
@Id
@GeneratedValue
@RevisionNumber
private Long id;
@RevisionTimestamp
private Long timestamp;
@Column(name = "user")
private String user;
}
public class AuditListener implements RevisionListener {
@Override
public void newRevision(Object revisionEntity) {
Audit audit = (Audit) revisionEntity;
audit.setUsuario("user");
}
}
我试图在我的实体 class 中扩展我的审计 class,但我对 JPA 有问题,问题是:
Caused by: org.hibernate.MappingException: Unable to find column with logical name: myId in org.hibernate.mapping.Table(TableNameAuditedLog) and its related supertables and secondary tables
我该怎么做?
谢谢大家
从审计中删除 MappedSuperClass class。您还可以让 Audit 扩展 DefaultRevisionEntity。您在 Audit class 中所拥有的只是您的自定义字段。
@Column(name = "user")
private String user;
自定义审计修订实体:
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@RevisionEntity(UserRevisionListener.class)
public class AuditRevisionEntity extends DefaultTrackingModifiedEntitiesRevisionEntity {
private static final long serialVersionUID = 1L;
private Long userId;
@Column(length = 100, nullable = false)
private String initiator;
}
和修改监听器
public class UserRevisionListener implements RevisionListener {
private static final String SYSTEM_USER = "System";
private transient final SecurityUtils securityUtils;
public UserRevisionListener(final SecurityUtils securityUtils) {
this.securityUtils = securityUtils;
}
@Override
public void newRevision(Object revisionEntity) {
final AuditRevisionEntity are = (AuditRevisionEntity) revisionEntity;
securityUtils.getPrincipal().ifPresentOrElse((appPrincipal) -> {
are.setUserId(appPrincipal.getUserId());
are.setInitiator(appPrincipal.getDisplayName());
}, () -> are.setInitiator(SYSTEM_USER));
}
}
在我的例子中,我使用 SecurityUtils 帮助程序获取当前主体(我正在使用具有额外字段的自定义主体)并根据需要设置 AuditRevisionEntity。 Quartz 作业进行了一些更改,因此没有主体,在这种情况下仅设置了启动器。
早上好,如何在审计中添加字段table?
我需要审计一些table,但我需要得到执行操作的用户。我将接受审计的实体是:
@Entity
@Table(name ="TableName")
@Audited
@AuditTable("TableNameAuditedLog")
public class MyEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "myId")
private Long id;
@Column(name = "myName")
private String name;
}
查看文档,我看到了一个自定义示例 class 作为我的审计和侦听器,所以我这样做了:
@Data
@RevisionEntity(AuditListener.class)
@MappedSuperclass
public class Audit {
@Id
@GeneratedValue
@RevisionNumber
private Long id;
@RevisionTimestamp
private Long timestamp;
@Column(name = "user")
private String user;
}
public class AuditListener implements RevisionListener {
@Override
public void newRevision(Object revisionEntity) {
Audit audit = (Audit) revisionEntity;
audit.setUsuario("user");
}
}
我试图在我的实体 class 中扩展我的审计 class,但我对 JPA 有问题,问题是:
Caused by: org.hibernate.MappingException: Unable to find column with logical name: myId in org.hibernate.mapping.Table(TableNameAuditedLog) and its related supertables and secondary tables
我该怎么做?
谢谢大家
从审计中删除 MappedSuperClass class。您还可以让 Audit 扩展 DefaultRevisionEntity。您在 Audit class 中所拥有的只是您的自定义字段。
@Column(name = "user")
private String user;
自定义审计修订实体:
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@RevisionEntity(UserRevisionListener.class)
public class AuditRevisionEntity extends DefaultTrackingModifiedEntitiesRevisionEntity {
private static final long serialVersionUID = 1L;
private Long userId;
@Column(length = 100, nullable = false)
private String initiator;
}
和修改监听器
public class UserRevisionListener implements RevisionListener {
private static final String SYSTEM_USER = "System";
private transient final SecurityUtils securityUtils;
public UserRevisionListener(final SecurityUtils securityUtils) {
this.securityUtils = securityUtils;
}
@Override
public void newRevision(Object revisionEntity) {
final AuditRevisionEntity are = (AuditRevisionEntity) revisionEntity;
securityUtils.getPrincipal().ifPresentOrElse((appPrincipal) -> {
are.setUserId(appPrincipal.getUserId());
are.setInitiator(appPrincipal.getDisplayName());
}, () -> are.setInitiator(SYSTEM_USER));
}
}
在我的例子中,我使用 SecurityUtils 帮助程序获取当前主体(我正在使用具有额外字段的自定义主体)并根据需要设置 AuditRevisionEntity。 Quartz 作业进行了一些更改,因此没有主体,在这种情况下仅设置了启动器。