You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Hibernate Envers时如何选择需要审计的字段?

Hibernate Envers 仅审计操作元数据的配置方案

核心需求是仅保留实体ID、操作时间、操作类型三个审计字段,不需要记录业务字段的变更,可通过以下两种方案实现:


方案一:全局配置(推荐,适合多实体通用需求)

该方案通过全局配置关闭默认全字段审计规则,仅需显式标注需要审计的字段即可,适配你当前基类+子类的实体结构。

第一步:添加Envers全局配置

在application.properties(或yml对应格式)中添加以下配置:

# 核心配置:默认所有字段不进入审计,仅显式标注@Audited的字段才会被记录
spring.jpa.properties.org.hibernate.envers.default_audited=false
# 关闭字段变更标记,不需要记录单字段变更状态
spring.jpa.properties.org.hibernate.envers.global_with_modified_flag=false

第二步:调整实体注解

修改基类BaseEntity,仅给主键标注@Audited:

@MappedSuperclass
public class BaseEntity {
    @Id
    @Audited
    private Long id;
    // 其余基类字段无需标注@Audited,不会被审计
    // getter and setter
}

修改业务实体类,仅在类上标注@Audited开启审计开关:

@Entity
@Audited
public class Entity extends BaseEntity {
    // 所有业务字段无需标注,不会被记录到审计表
    // getters and setters
}

方案二:单实体适配(无需全局配置,适合单个实体需求)

如果仅需要给这一个实体做精简审计,不需要修改全局配置,直接给不需要审计的字段标注@NotAudited即可:

@Entity
@Audited
public class Entity extends BaseEntity {
    @NotAudited
    private String field1;
    @NotAudited
    private Integer field2;
    // 其余业务字段都加@NotAudited,仅会保留主键、操作类型、修订关联字段
    // getters and setters
}

审计表结构说明

配置完成后自动生成的实体审计表会包含三个核心字段:

  • id:对应你的业务实体主键
  • REVTYPE:操作类型,0=新增、1=更新、2=删除
  • REV:修订版本号,关联系统默认的REVINFO审计总表,REVINFO表中REVTSTMP字段就是操作时间戳

审计记录查询示例

可以通过AuditReader快速查询指定实体的所有操作记录:

@Component
public class AuditService {
    @PersistenceContext
    private EntityManager entityManager;

    public List<AuditRecordDTO> getEntityHistory(Long entityId) {
        AuditReader auditReader = AuditReaderFactory.get(entityManager);
        List<Object[]> rawRecords = auditReader.createQuery()
                .forRevisionsOfEntity(Entity.class, false, true)
                .add(AuditEntity.id().eq(entityId))
                .getResultList();
        
        // 组装返回结果,从修订对象中拿操作时间,从返回参数拿操作类型和实体ID
        return rawRecords.stream().map(record -> {
            Entity entity = (Entity) record[0];
            DefaultRevisionEntity revision = (DefaultRevisionEntity) record[1];
            RevisionType type = (RevisionType) record[2];
            return new AuditRecordDTO(
                    entity.getId(),
                    revision.getRevisionDate(),
                    type.name()
            );
        }).toList();
    }
}

内容的提问来源于stack exchange,提问作者vlad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 04:54:08