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

Hibernate Envers在无成员字段的派生类中无法生成审计日志

问题描述

定义了基类Account,使用@Audited开启审计,采用SINGLE_TABLE继承策略:

import org.hibernate.envers.Audited;

@Audited
@Entity
@Table(
    name = "account",
    indexes = {
      @Index(name = "account_currency_id_idx", columnList = "currency_id")
    })
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "account_type")
public class Account {

  @Id
  @GeneratedValue
  @Setter(AccessLevel.NONE)
  @NotNull
  private Long id;

  @Audited
  @LastModifiedDate
  @Column(name = "last_modified_date_time")
  @Setter(AccessLevel.NONE)
  private LocalDateTime lastModifiedDateTime;

  @Audited
  @LastModifiedBy
  @Setter(AccessLevel.NONE)
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "last_modified_by_user_id", referencedColumnName = "id")
  @Audited(targetAuditMode = NOT_AUDITED)
  private User lastModifiedByUser;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "currency_id", referencedColumnName = "id")
  @ApiFieldMappingProperty("currencyId")
  @Audited(targetAuditMode = NOT_AUDITED)
  private Currency currency;

  @NotNull
  @Column(name = "open_date", nullable = false)
  private LocalDate openDate;

  @Column(name = "close_date")
  private LocalDate closeDate;

  // 其他成员与方法
}

随后定义两个无额外字段的派生类,仅通过鉴别器值区分账户类型:

// DomesticAccount.java
@Entity(name = "domestic_account")
@DiscriminatorValue("DOMESTIC")
public DomesticAccount extends Account {
}
// OffshoreAccount.java
@Entity(name = "offshore_account")
@DiscriminatorValue("OFFSHORE")
public OffshoreAccount extends Account {
}

代码中始终实例化并保存DomesticAccount或OffshoreAccount,从不直接使用Account类,但ACCOUNT_AUD审计表始终为空,变更未被记录。

问题原因与解决方案
  • 核心问题:Hibernate Envers在单表继承场景下,仅给基类添加@Audited不足以让派生类的变更被审计。因为实际操作的是派生类实体,Envers需要明确每个实体类都启用审计机制。
  • 解决方法:给两个派生类都添加@Audited注解:
    @Audited
    @Entity(name = "domestic_account")
    @DiscriminatorValue("DOMESTIC")
    public DomesticAccount extends Account {
    }
    
    @Audited
    @Entity(name = "offshore_account")
    @DiscriminatorValue("OFFSHORE")
    public OffshoreAccount extends Account {
    }
    
  • 补充说明:
    • 若基类的@Audited设置了inheritAuditStrategy = InheritAuditStrategy.SUPERCLASS_AUDITING,理论上派生类会继承审计配置,但实际场景中(尤其是直接操作派生类时),显式添加@Audited更可靠。
    • 既然ACCOUNT_AUD表已生成,说明Envers基础配置无误,问题就出在派生类未启用审计。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 00:24:17