Dum*_*mbo 4 java hibernate jpa hibernate-annotations hibernate-envers
我想问一下如何使用诸如@AuditOverride
,@Audited
或 else 之类的休眠注释来审计实体超类的一部分。现在,我使用的是 hibernate 5.2.12 版本。
我只能在子类中使用的注释,因为超类在其他模块中,它不应该知道关于子模块的任何信息。
超类包含一个List<Items>
,我不希望它被审计。因为当我使用one-to-many
关系时,我不希望休眠会创建审计关系表,例如entity1_aud_entity2_aud。我只需要entity1_aud和entity2_aud表。
拒绝审计关系表我找到了两种方法,但都不完全正确:
我将列表变量和 setter/getter 复制到实体(subclass)。上面的列表变量我写了@NotAudited
注释。为了使该注释起作用,我access="field"
在hbm
文件中设置了属性。因此休眠不使用 setter 和 getter 访问变量,因此在数据拉取期间未设置超类的值。
我还创建了我写的列表实体@AuditOverrides(value={@AuditOverride(forClass=Entity2.class), @AuditOverride(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);
}
}
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
Entity2.class(列表项子类)【休眠模块】
@AuditOverrides({
@AuditOverride(forClass = Entity2.class),
@AuditOverride(forClass = Item.class)})
public class Entity2 extends Item {
}
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
Item.class(列表项超类)【领域模块】
public class Item extends Builder {
private String item;
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
}
Run Code Online (Sandbox Code Playgroud)
RESULT:
During data pulling from database only entity1 list will be set. The superclass list will be null, because of access="field"
in hbm file.
I removed access="field"
attribute and started playing only with @AuditOverride
annotations.
If I leave everything as in 1st. way, just remove the access
attribute and the list in entity class, superclass will not be audited at all. So audit table fields will be null.
If I add additional @AuditOverride(forClass=Superclass.class)
- all super class will be audited including the list even @AuditOverride(forClass=Superclass.class, name="list", isAudited=false)
also is written. So I tried modify only:
Entity1.class (sublcass) [hibernate module]
/* @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 {
}
Run Code Online (Sandbox Code Playgroud)
有两个选项,并且都有相同的结果。
结果:
超类被审计,但列表也将被审计。所以这意味着将创建审计关系(entity1_aud_entity2_aud)。
第一个。方法不是在数据拉取期间将数据设置到超类。第二。方式 - 审核所有超类,而我只需要审核其中的一部分。所以问题是:
有没有其他方法可以在子类中使用注解并且只审计超类的一部分?
(请务必在回答前阅读所有问题信息)
谢谢
根据您的问题,您应该能够按如下方式注释您的实体:
@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
}
Run Code Online (Sandbox Code Playgroud)
我只使用@AuditOverride
/@AuditOverrides
注释来控制对超类型及其属性的审计,并@Audited
指示应审计实体类型。
我还说明了Entity1
如何在您可能希望审核大多数属性并排除一个子集或反之亦然的情况下混合各种覆盖。
这里的最终结果是您的Entity1_AUD
表将包含您的所有属性,Entity1
并且还将包含您的SuperClass
类中的所有属性,不包括您的list
属性。您的Entity2_AUD
表将包含来自Entity2
和超类的所有属性Item
。此外,在Entity1
和Entity2
for之间不会有经过审计的连接表list
。
归档时间: |
|
查看次数: |
3006 次 |
最近记录: |