如何在休眠中只审计超类的一部分?

How to audit just part of superclass in hibernate?

我想问一下如何使用 @AuditOverride@Audited 等休眠注解仅审计实体的超 class 的一部分。现在,我使用的是hibernate 5.2.12版本。
我只能在 sublcass 中使用注释,因为 superclass 在其他模块中,不应该知道任何关于子模块的信息。
Superclass 包含一个 List<Items>,我不希望它被审计。因为当我使用 one-to-many 关系时,我不希望 hibernate 会创建审计关系 table,例如 entity1_aud_entity2_aud。我只需要 entity1_audentity2_aud tables.
拒绝审计关系table我找到了两种方法,但都不完全正确:

第一。方式

我将列表变量和 setters/getters 复制到实体 (subclass)。在列表变量上方我写了 @NotAudited 注释。为了使该注释起作用,我在 hbm 文件中设置了 access="field" 属性。所以休眠不使用 setter 和 getter 来访问变量,所以 superclass 的值在数据拉动期间没有设置 .
我还创建了列表实体,其中我写了 @AuditOverrides(value={@AuditOverride(forClass=Entity2.class), @AuditOverride(forClass=Item.class)})。这些注释为列表实体创建审计 table。这种审计方式的完整代码是:
Entity1.class(主子类)[休眠模块]

@AuditOverrides(value = {
        @AuditOverride(forClass = Entity1.class),
        @AuditOverride(forClass = Superclass.class, name = "list", isAudited = false)
})
public class Entity1 extends Superclass {

    @NotAudited
    private List<Item> list = new ArrayList<>();

    @Override
    public List<Item> getList() {
        return super.getList();
    }

    @Override
    public void setList(List<Item> list) {
        super.setList(list);
    }
}  

Entity1.hbm.xml

<?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" cascade="all" lazy="false" access="field">
            <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>  

Superclass.class [域模块]

public class Superclass extends Builder {

    private List<Item> list = new ArrayList<>();
    private String other;

    public List<Item> getList() {
        return list;
    }

    public void setList(List<Item> list) {
        this.list = list;
    }

    public String getOther() {
        return other;
    }

    public void setOther(String other) {
        this.other = other;
    }
}  

Entity2.class (列表项子class) [休眠模块]

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

Entity2.hbm.xml

<?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.Entity2" table="entity2">
        <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_list</param>
            </generator>
        </id>

        <property name="item" column="item" type="string" length="15"/>
    </class>
</hibernate-mapping>  

Item.class (list item superclass) [domain module]

public class Item extends Builder {

    private String item;

    public String getItem() {
        return item;
    }

    public void setItem(String item) {
        this.item = item;
    }
}  

结果:
在从数据库中提取数据时,只会设置 entity1 列表。由于 hbm 文件中的 access="field",superclass 列表将为空。

第二。方式

我删除了 access="field" 属性并开始只使用 @AuditOverride 注释。
如果我将所有内容都保留为 1st。 way,只要去掉access属性,entityclass中的列表,superclass根本不会被审计。所以审计 table 字段将为空。
如果我添加额外的 @AuditOverride(forClass=Superclass.class) - 所有超级 class 都将被审核,包括列表甚至 @AuditOverride(forClass=Superclass.class, name="list", isAudited=false) 也被写入。所以我只尝试修改:

Entity1.class (sublcass) [休眠模块]

/* @AuditOverrides(value = {
        @AuditOverride(forClass = Entity1.class),
        @AuditOverride(forClass = Superclass.class, name = "other", isAudited = true),
        @AuditOverride(forClass = Superclass.class, name = "list", isAudited = false)
* OR */
@AuditOverrides(value = {
        @AuditOverride(forClass = Entity1.class),
        @AuditOverride(forClass = Superclass.class),
        @AuditOverride(forClass = Superclass.class, name = "list", isAudited = false)
})
public class Entity1 extends Superclass {
}  

有两个选项,结果相同。
结果:
superclass 已被审核,但列表也将被审核。因此,这意味着将创建审计关系 (entity1_aud_entity2_aud)。

结论

第一名。方法是在数据拉取期间不将数据设置到 superclass。第二个。方式 - 审核所有 superclass,而我只需要审核其中的一部分。所以问题是:
是否有任何其他方法可以在 subclass 中使用注释并仅审计 superclass 的一部分?

(请务必在回答前阅读所有问题信息)
谢谢

根据您的问题,您应该能够按如下方式注释您的实体:

@Entity
@Audited
@AuditOverrides({
  @AuditOverride(forClass = SuperClass.class, isAudited = true),
  @AuditOverride(forClass = SuperClass.class, name = "list", isAudited = false)
})
public class Entity1 extends SuperClass {
  // just put your entity1 attributes here, no need to duplicate anything
}

@Entity
@Audited
@AuditOverride(forClass = Item.class, isAudited = true)
public class Entity2 extends Item {
  // just put your entity2 attributes here, no need to duplicate anything
}

我只使用 @AuditOverride / @AuditOverrides 注释来控制对超类型及其属性的审计,并使用 @Audited 来表示实体类型应该被审计。

我还在 Entity1 上说明了在您希望审计大部分属性并排除子集或反之亦然的情况下如何混合各种覆盖。

这里的最终结果是您的 Entity1_AUD table 将包含您在 Entity1 中的所有属性,并且还将包含您的 SuperClass class 中的所有属性] 不包括您的 list 属性。您的 Entity2_AUD table 将包含 Entity2 和超级 class Item 的所有属性。此外,对于 list.

,在 Entity1Entity2 之间将不会有经过审核的 join-table