如何在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
相关产品推荐
相关产品推荐

