我有一个经典的继承持久化实体Parent和Child,其中Child扩展Parent.类Parent是抽象的,而Child不是.
我想审核孩子.这个实体在我的控制之下,而Parent则不在.此外,它还有许多其他不需要审计的子类.整个层次结构的继承策略是JOINED.
所以我用@Audited注释了Child,另外还有@AuditOverride(forClass = Parent.class).
我得到的是这个错误:
"org.hibernate.MappingException:实体'Child'被审计,但是它的超类:'Parent'不是."
顺便说一下,我正在使用envers 4.0.1.Final版本.
有谁知道我怎么能做到这一点? 我试图消除@Audited在儿童类,除去@AuditOverride,使用过时auditParents在@Audited注释,但似乎没有任何工作.
这是Parent实体:
@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); } }
最后这里是土豆:
先感谢您!