将自定义字段添加到 Hibernate Envers 修订表 (revinfo),如 operation_id。哪个是操作实体的PK
Posted
技术标签:
【中文标题】将自定义字段添加到 Hibernate Envers 修订表 (revinfo),如 operation_id。哪个是操作实体的PK【英文标题】:Add custom field to Hibernate Envers revision table (revinfo), like operation_id. Which is a PK of Operation entity 【发布时间】:2021-09-09 02:48:07 【问题描述】:您好,我想知道是否可以将像 Operation_id 这样的自定义字段添加到 revinfo 表中,该字段将具有自定义操作,如 ADD_TRAVEL_OP。这些操作应该在每个端点中静态或动态设置。
@Entity
@Table(name = "revinfo")
@RevisionEntity(AuditRevisionListener.class)
public class AuditRevisionEntity extends DefaultRevisionEntity implements Serializable
@Column(name = "rev")
private int revision;
private String username;
private String operationId;
public int getRevision()
return revision;
public void setRevision(final int revision)
this.revision = revision;
public String getUsername()
return username;
public void setUsername(final String userName)
this.username = userName;
public String getOperationId()
return operationId;
public void setOperationId(final String operationId)
this.operationId = operationId;
@Configuration
public class AuditRevisionListener implements RevisionListener
@Override
public void newRevision(Object revisionEntity)
final AuditRevisionEntity are = (AuditRevisionEntity) revisionEntity;
final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication instanceof UserDetails)
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
are.setUsername(userDetails.getUsername());
else
are.setUsername(authentication.getName());
【问题讨论】:
【参考方案1】:当然,您可以向 AuditRevisionEntity 添加字段。诀窍是您必须有权访问 AuditRevisionListener 中的数据。我要求某些操作需要在审计跟踪 (AuditRevisionEntity) 中记录更改原因。我最终使用本地线程来存储更改原因,使用本地线程在 AuditRevisionListener 中设置更改原因,并在事务开始或完成时清除本地线程。
JpaTransactionManager 实现:
public class AuditingJpaTransactionManager extends JpaTransactionManager
private final AuditContextHolder auditContextHolder = new AuditContextHolder();
public AuditingJpaTransactionManager()
super();
public AuditingJpaTransactionManager(EntityManagerFactory emf)
super(emf);
@Override
protected void doBegin(Object transaction, TransactionDefinition definition)
this.auditContextHolder.clearContext();
super.doBegin(transaction, definition);
@Override
protected void doCleanupAfterCompletion(Object transaction)
this.auditContextHolder.clearContext();
super.doCleanupAfterCompletion(transaction);
线程本地实现:
public class AuditContextHolder
private static final ThreadLocal<AuditContext> contextHolder = new ThreadLocal<>();
public void clearContext()
contextHolder.remove();
public AuditContext getContext()
AuditContext ctx = contextHolder.get();
if (ctx == null)
ctx = new AuditContext();
contextHolder.set(ctx);
return ctx;
@NoArgsConstructor
public static class AuditContext
@Getter
@Setter
private String reasonForChange;
【讨论】:
【参考方案2】:所以在 Lee Greiner 的帮助下,我实现了我的目标。我会把剩下的留在这里,这很明显,但仍然可以帮助其他人。
//update to what i already had
public class AuditRevisionListener implements RevisionListener
@Override
public void newRevision(Object revisionEntity)
final AuditRevisionEntity are = (AuditRevisionEntity) revisionEntity;
final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication instanceof UserDetails)
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
are.setUsername(userDetails.getUsername());
else
are.setUsername(authentication.getName());
String operationId = new AuditContextHolder().getContext().getOperationId();
if(operationId == null) operationId = Operation.NOT_DEFINED.name();
are.setOperationId(operationId);
//Set the desired Operation before the save point
new AuditContextHolder()
.getContext()
.setOperationId(Operation.LOGIN_OP.name());
【讨论】:
以上是关于将自定义字段添加到 Hibernate Envers 修订表 (revinfo),如 operation_id。哪个是操作实体的PK的主要内容,如果未能解决你的问题,请参考以下文章
使用 paypal 节点 sdk 将自定义字段添加到计费协议