gpt4 book ai didi

java - hibernate 环境 : @Audited on a subclass

转载 作者:搜寻专家 更新时间:2023-10-30 19:46:46 25 4
gpt4 key购买 nike

我有实体 ParentChild 的经典继承持久性,其中 Child 扩展 Parent。类 Parent 是抽象的,而 Child 不是。

我想审计这个实体在我的控制之下,而则不是。此外,它还有许多其他不需要审核的子类。整个层级的继承策略是JOINED

所以我用 @Audited@AuditOverride(forClass = Parent.class)Child 进行了注释。

我得到的是这个错误:

"org.hibernate.MappingException: Entity 'Child' is audited, but its superclass: 'Parent' is not."

顺便说一下,我使用的是 envers 4.0.1.Final 版本。

有谁知道我怎样才能做到这一点?我已经尝试删除 Child 类中的 @Audited,删除 @AuditOverride,在 中使用已弃用的 auditParents @Audited 注释,但似乎没有任何效果。

这是父实体:

@Entity
@Table(name = "parent")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "type")
public class Parent {
public Parent() {
super();
}

@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "base_id", unique = true, nullable = false)
private Integer baseId;

@Column(name = "base_field")
private String baseField;

@Column(name = "type")
private String type;

// getters and setters
}

这是我的子实体:

@Entity
@Table(name = "child")
@DiscriminatorValue("CHILD")
@Audited
@AuditOverride(forClass = Parent.class)
public class Child extends Parent {
public Child() {
super();
}

@Column(name = "child_field")
private String childField;

// getters and setters
}

这是实体:

CREATE  TABLE `REVINFO` (
`REV` BIGINT NOT NULL AUTO_INCREMENT,
`REVTSTMP` BIGINT NULL ,
PRIMARY KEY (`REV`)
);

CREATE TABLE `parent` (
`base_id` int(11) NOT NULL AUTO_INCREMENT,
`base_field` varchar(45) DEFAULT NULL,
`type` varchar(45) NOT NULL,
PRIMARY KEY (`base_id`)
);

CREATE TABLE `child` (
`base_id` int(11) NOT NULL AUTO_INCREMENT,
`child_field` varchar(45) DEFAULT NULL,
PRIMARY KEY (`base_id`)
);

CREATE TABLE `child_AUD` (
`base_id` int(11) NOT NULL,
`REV` BIGINT NOT NULL,
`REVTYPE` tinyint(2) DEFAULT NULL,
`child_field` varchar(45) DEFAULT NULL,
PRIMARY KEY (`base_id`,`REV`)
);

这是一个测试用例:

public class EnversInheritanceTest extends AbstractJUnit4SpringContextTests {

@Inject
private EntityManagerFactory entityManagerFactory;

private EntityManager entityManager;

@Test
public void inheritanceTest() {

this.entityManager = this.entityManagerFactory.createEntityManager();

Child child = this.createChild();
this.saveChild(child);

this.modifyChild(child);
this.saveChild(child);

Assert.assertNotNull(child.getBaseId());
Assert.assertNotNull(this.getOriginalRevision(child.getBaseId()));

Child original = this.getOriginalChild(child.getBaseId());

Assert.assertNotNull(original);
Assert.assertEquals("child", original.getChildField());

}

private Child createChild() {
Child child = new Child();
child.setBaseField("base");
child.setChildField("child");
child.setType("CHILD");
return child;
}

private void saveChild(Child child) {
this.entityManager.getTransaction().begin();
this.entityManager.persist(child);
// We need to commit in order to trigger Envers magic
this.entityManager.getTransaction().commit();
}

private void modifyChild(Child child) {
child.setBaseField("foo");
child.setChildField("bar");
}

public Child getOriginalChild(Serializable id) {
Object queryResult = this.getAuditReader().createQuery()
.forEntitiesAtRevision(Child.class, this.getOriginalRevision(id))
.add(AuditEntity.id().eq(id))
.getSingleResult();
return (Child) queryResult;
}

private Number getOriginalRevision(Serializable id) {
AuditProjection minRevNumberAuditProjection = AuditEntity.revisionNumber().min();
Number revision = (Number) this.getAuditReader().createQuery()
.forRevisionsOfEntity(Child.class, false, false)
.add(AuditEntity.id().eq(id))
.addProjection(minRevNumberAuditProjection)
.getSingleResult();

return revision;
}

private AuditReader getAuditReader() {
return AuditReaderFactory.get(this.entityManager);
}

}

提前致谢!

最佳答案

一个很好的问题。有 same discussion在 2013 年的 jboss 开发者论坛上。答案来自the founder and project lead of Hibernate Enver :

You would have to get the superclass audited somehow. Currently there's no other way to specify such metadata except for annotations.

在同一个讨论树中,根据一个父类也要注解的事实,建议在Runtime中注解它们。但是这个决定似乎很丑陋并且不适合您的情况:您可以手动注释父类。

作为变通方法,如果您不希望父类被审计,您可以尝试创建一个基础抽象 MappedSuperClass,它基本上与 Parent 相同,而 Parent 将只是它的后代,然后尝试为 Child 类再次放置 @AuditOverride。它可能会“跳过”对 Parent 类的审核,而对 Child 进行审核。

关于java - hibernate 环境 : @Audited on a subclass,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34297427/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com