提问者:小点点

如何在hibernate中审计超类的一部分?


我想问如何审计实体超类的一部分,使用Hibernate注释,如@AuditOverrid@Auded或其他。现在,我正在使用hibernate 5.2.12版本。
我只能在子类中使用注释,因为超类在其他模块中,它不应该知道任何关于子模块的信息。
超类包含一个列表

我将列表变量和setter/getter复制到实体(子类)。在列表变量上方,我编写了@NotAuded注释。为了使注释正常工作,我在hbm文件中设置了access="field"属性。因此Hibernate不使用setter和getter访问变量,因此在数据提取期间不会设置超类的值。
我还创建了列表实体,其中我编写了@AuditOverrides(value={@AuditOverrid(forClass=Entity2. class),@AuditOverrid(forClass=Item.class)})。这些注释为列表实体创建了审计表。因此这种审计方式的完整代码是:
Entity1.class(main sublcass)[hibernate module]

@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);
    }
}  

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(列表项子类)【Hibernate模块】

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

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(列表项超类)【领域模块】

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"

我删除了access="field"属性,开始只使用@AuditOverride注释。
如果我把所有东西都留在第一。方式,只需删除access属性和实体类中的列表,超类将根本不会被审计。所以审计表字段将为空。
如果我添加额外的@AuditOverrid(forClass=Superclass. class)-所有超类都将被审计,包括列表甚至@AuditOverrid(forClass=Superclass.class,name="list",isAuded=false)也写了。所以我尝试只修改:

Entity1. class(子类)[Hibernate模块]

/* @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 {
}  

有两个选项,它们都有相同的结果。
结果:
超类被审计,但列表也将被审计。这意味着将创建审计关系船(entity1_aud_entity2_aud)。

第一种方法是在数据提取过程中不将数据设置为超类。第二种方法-审计所有超类,而我只需要审计其中的一部分。所以问题是:
还有其他方法可以在子类中使用注释并且只审计超类的一部分吗?

(确保你在回答之前阅读了所有的问题信息)
谢谢


共1个答案

匿名用户

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

@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
}

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

我还在Entity1上说明了如何在您可能想要审计大多数属性并排除子集或反之亦然的情况下混合各种覆盖。

这里的最终结果是,您的Entity1_AUD表将包含来自Entity1的所有属性,并且还将包含来自您的SuperClass类的所有属性,不包括您的list属性。您的Entity2_AUD表将包含来自Entity2和超级类Item的所有属性。此外,listEntity1Entity2之间不会有经过审计的连接表。