如何不使用 Hibernate Envers 审计连接表和相关实体?

Posted

技术标签:

【中文标题】如何不使用 Hibernate Envers 审计连接表和相关实体?【英文标题】:How not to audit a join table and related entities using Hibernate Envers? 【发布时间】:2012-07-12 01:43:44 【问题描述】:

我使用 Hibernate Envers 来审计我的实体。

我有一个审计实体Foo,它有一个List<Bar> 作为属性。但是,我不想审核 Bar 实体。因此,我写道:

@Entity
@Audited
public class Foo 

    @JoinTable(name = "T_FOO_BAR", joinColumns = @JoinColumn(name = "FOO_ID"), inverseJoinColumns = @JoinColumn(name = "BAR_ID"))
    @ManyToMany(cascade = PERSIST)
    @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
    public List<Bar> getBars() 
        return bars;
    


现在,我想检索 Foo 的修订:

    AuditReader reader = AuditReaderFactory.get(getEntityManager());
    Foo revision = (Foo) reader.createQuery().forEntitiesAtRevision(Foo.class, 42).getSingleResult();

不幸的是,当我想检索所有数据时(即当它延迟加载 bars 时),我收到错误 ORA-00942: table or view does not exist,因为它试图查询:

select ... from T_FOO_BAR_AUD x, T_BAR y where ...

我虽然使用@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED),但Hibernate Envers 会保留与当前 实体的Bar 项的链接。

那么我怎样才能解决我的问题,而不必明确审核表T_BART_FOO_BAR(连接表)?换句话说,当我从我的修订实体中检索bars 的列表时,我会从我当前的实体中获得bars 的列表(因为FooBar 之间的链接没有经过审核)。

谢谢。

【问题讨论】:

【参考方案1】:

看起来你使用的是@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED),而你应该使用@NotAudited

RelationTargetAuditMode.NOT_AUDITED 根本不会审核目标实体。它仍然会尝试审计FooList&lt;Bar&gt; 属性,从而审计连接表。

来自文档:

如果你想审计一个关系,目标实体不是 已审计(例如类似字典的实体就是这种情况, 不会改变也不必被审计),只需注释它 与@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)。 然后,在读取实体的历史版本时,关系将 始终指向“当前”相关实体。

【讨论】:

以上是关于如何不使用 Hibernate Envers 审计连接表和相关实体?的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate-Envers:审计动态组件

Hibernate envers如何向审计表添加字段

Hibernate Envers:如何从我的审计表中删除条目?

审计没有 Hibernate Envers 的 java 实体

Hibernate Envers:初始化 Envers 代理

Hibernate Envers - 在启动时填写审计表