使用Hibernate Envers如何避免未预期的Person审计插入?
问题:Envers持久化PersonPreference时生成多余的Person审计记录
实体代码
PersonPreference类
public class PersonPreference { @Id private Long id; @EntityId(value = Person.class, defer = false) @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "PERSON", nullable = false, insertable = true, updatable = false) @SensitiveData private Person person; }
Person类
public class Person { @Id @GeneratedValue(generator = MY_SEQUENCE_GENERATOR_NAME, strategy = GenerationType.SEQUENCE) @SequenceGenerator(name = MY_SEQUENCE_GENERATOR_NAME, sequenceName = MY_SEQUENCE_GENERATOR_NAME, allocationSize = 1) private Long id; @OneToMany(fetch = FetchType.LAZY, mappedBy = "person") private List<PersonPreference> personPreferences = new ArrayList<>(0); }
操作代码
Person existingPerson = EM.find(Person.class, personId); personPreference.setPerson(existingPerson); EM.persist(personPreference); EM.flush();
问题现象
执行上述代码后,数据库产生三个操作:
- 插入数据至
Person_Preference表 - 插入数据至
Z_Person_Preference审计表 - 多余插入数据至
Z_Person审计表(Person实体未发生任何变更)
解决方法
方法1:修改Person类的关联注解,排除集合变更审计
在Person的@OneToMany注解上添加@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED),告知Envers不要因该关联集合的变化触发Person实体审计:
@OneToMany(fetch = FetchType.LAZY, mappedBy = "person") @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED) private List<PersonPreference> personPreferences = new ArrayList<>(0);
此方法适合需要保留Person自身变更审计,但不想因关联的PersonPreference增减生成Person审计记录的场景。
方法2:以只读模式获取Person实体
获取Person时使用只读锁模式,让Hibernate不将该实例纳入脏检查逻辑,从而避免Envers触发审计:
Person existingPerson = EM.find(Person.class, personId, LockModeType.READ); personPreference.setPerson(existingPerson); EM.persist(personPreference); EM.flush();
此方法仅作用于当前操作,不会影响其他场景下Person的正常审计逻辑。
方法3:移除Person类的@Audited注解(按需使用)
如果完全不需要审计Person实体的任何变化,直接在Person类上移除@Audited注解即可,仅适用于不需要Person审计记录的场景。
内容的提问来源于stack exchange,提问作者budducci
相关产品推荐
相关产品推荐

