【问题标题】:How to add fields in audit table using Envers in Spring Boot如何在 Spring Boot 中使用 Envers 在审计表中添加字段
【发布时间】:2021-03-14 13:36:03
【问题描述】:

早上好,如何在我的审计表中添加字段?

我需要审计一些表,但我需要获取执行操作的用户。我将被审计的实体是:

@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;
}

查看文档,我看到了一个示例,一个自定义类作为我的审计和监听器,所以我做了这样的:

@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");
    }
}

我尝试在我的 Entity 类中扩展我的 Audit 类,但 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。请检查没有它是否有效。
  • 我删除了注释,更正了错误,但我的用户继续在 revinfo 中保存 null
  • 我忘记将我的审计类注释为@Entity

标签: java spring-boot hibernate hibernate-envers


【解决方案1】:

从您的 Audit 类中删除 MappedSuperClass。您还可以让 Audit 扩展 DefaultRevisionEntity。您在 Audit 类中所拥有的只是您的自定义字段。

@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 作业进行了一些更改,因此没有主体,在这种情况下,仅设置了启动器。

【讨论】:

  • 谢谢,它现在可以工作了,我忘了把我的审计类也注释为@Entity
猜你喜欢
  • 2018-12-28
  • 2020-08-02
  • 1970-01-01
  • 2015-03-14
  • 2017-07-09
  • 2019-08-27
  • 2021-09-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多