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

如何在Hibernate 5.2.12中仅审计实体父类的部分属性?

解决方案:在子类精准控制父类属性的审计范围

针对你的问题,我在Hibernate Envers 5.x版本中处理过类似的场景——父类在独立模块无法修改,只能在子类控制审计范围。你的核心需求是审计父类的部分属性但排除集合,同时避免生成关联审计表,下面是可行的解决方案:

核心思路

不需要在子类重复定义父类的集合属性(这会导致映射冲突,出现属性为null的问题),而是通过@AuditOverride注解直接在子类中覆盖父类特定属性的审计状态,同时确保集合实体自身被审计以生成独立的审计表。

正确的代码配置

1. 子类Entity1的注解调整

在子类上添加@Audited启用审计,然后通过@AuditOverrides先启用父类的审计,再单独排除集合属性的审计:

@Entity
@Audited
@AuditOverrides({
    // 启用父类Superclass的审计(默认包含所有属性)
    @AuditOverride(forClass = Superclass.class),
    // 单独覆盖父类的list属性,设置为不审计
    @AuditOverride(forClass = Superclass.class, name = "list", isAudited = false)
})
public class Entity1 extends Superclass {
    // 无需重复定义list属性,直接继承父类的即可
}

2. Entity1.hbm.xml映射调整

移除access="field"配置,保持集合映射指向父类的list属性:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="testing.Entity1" table="entity1">
        <id name="id" column="id">
            <generator class="org.hibernate.id.enhanced.SequenceStyleGenerator">
                <param name="optimizer">none</param>
                <param name="increment_size">1</param>
                <param name="sequence_name">seq_entity_main</param>
            </generator>
        </id>
        <!-- 映射父类的list集合,name对应父类的私有属性 -->
        <list name="list" cascade="all" lazy="false">
            <key>
                <column name="entity1_id" index="idx_fk_enm_entity_id"/>
            </key>
            <list-index>
                <column name="list_index" not-null="true" default="0"/>
            </list-index>
            <one-to-many class="testing.Entity2"/>
        </list>
        <property name="other" column="other" type="string" length="50"/>
    </class>
</hibernate-mapping>

3. 集合子类Entity2的审计配置

确保Entity2添加@Audited以生成独立的审计表:

@Entity
@Audited
@AuditOverrides({
    @AuditOverride(forClass = Item.class)
})
public class Entity2 extends Item { }

为什么你的之前方案失败?

  • 方案1问题:重复定义父类的list属性,加上access="field"配置后,Hibernate会优先映射子类的list字段,而子类的getter返回父类的集合,导致查询时父类的集合未被赋值,出现null。
  • 方案2问题:大概率是缺少@Audited注解(Envers需要这个注解启用审计),或者@AuditOverride的顺序错误——必须先启用父类的全局审计,再单独覆盖特定属性的审计状态。

最终效果

  • 生成entity1_aud表,包含父类的other属性(被审计),不包含list的关联审计字段。
  • 生成entity2_aud表,记录集合项的变更。
  • 不会生成entity1_aud_entity2_aud这类关联审计表,因为父类的list已被标记为不审计。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:14:37