Hibernate Envers 审计非审计实体

Hibernate Envers auditing non audited entities

我的项目中有几个 classes 由 Hibernate 处理,一些由 Envers 审计,一些不是。现在,当我尝试保存某个未经审计的实体时,我得到了这个:

java.sql.SQLException: [SQLITE_ERROR] SQL error or missing database (no such table: audit_etc_etc)

有些人可能认为我的数据库中没有审计-table,但 Envers 甚至不应该尝试寻找这个 table,因为实体不是审核。我的 classes 看起来像这样:

@Entity
class A {
    /* some 'normal' attributes here */

    @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
    AuditedEntity e;

    List<B> listOfBs;
}

@Entity
class B {
    /* more 'normal' attributes here */

    @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
    AuditedEntity e; // and some more references to audited entities

    A anA;

    List<C> listOfCs;
}

@Entity
class C {
    /* more 'normal' attributes here */

    @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
    AuditedEntity e; // and some more references to audited entities

    B anB;
}

因此每个 class 都包含一个子项列表,其中包含对其父项的引用。 None 其中 class 标有 @Audited 注释,但它们引用了一些已审计的实体。然而,这些参考文献中的每一个都标有 @Audited(targetAuditMode = RelationTargetAuditMode. NOT_AUDITED)-注释。

我在 hibernate.cfg.xml 文件中也没有发现任何异常,只有连接详细信息、环境选项、class 映射和其他一些休眠选项。

这里有什么问题,我该如何解决保存时出现的这个问题?

(注意:我现在只对 classes A 和 B 进行了测试,但我假设尝试保存 C 的实例将抛出相同的异常)

更新:
当我尝试保存 B 实例时,启用 show_sql 显示:

Hibernate: update table_b set all_attributes=? where idB=?
Hibernate: insert into audit_description (timestamp, description) values (?, ?)
Hibernate: insert into audit_table_b (revision_type, attributes, moreAttributes, revision) values (?, ?, ?, ?)

事实证明,@Audited(...) 导致 Envers 审计实体,从而尝试写入不存在的审计表。将 @NotAudited 添加到每个 @Audited(..) 解决了我的问题,也许你根本不需要这两个注释。

问题是您将您的属性标记为@Audited,因此envers 尝试将它们作为它所属的Class 和class 本身的一部分进行审核。 您应该只用 @Audited 标记您的 classes 声明和其中您要审核的属性:

@Audited
@Entity
public class AuditedEntity{
  ...
}

并且您未审核 classes

@Entity
class A {
    AuditedEntity e;
    ...
}

如果您在另一个被审计的实体中使用 AuditedEntity:

@Entity
@Audited
public class AnotherAuditedEntity {
    @Audited
    AuditedEntity e;
    ...
}

问题是您放置 @Audited 注释来标记 non-audited 关系。与其将该注释放在您的实体 ABC 中,不如将这些注释放在您的实体 E 中与 AB, 和 C.

换句话说:

@Entity
@Audited
public class E {
  @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
  private A a;
  @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
  private B b;
  @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)     
  private C c;
}

希望对您有所帮助。