HHH-3843 - Fix and test

This commit is contained in:
Lukasz Antoniak 2011-10-19 20:07:49 +02:00
parent 09d40d1785
commit 86482c630b
6 changed files with 399 additions and 4 deletions

View File

@ -231,7 +231,7 @@ public abstract class BaseEnversCollectionEventListener extends BaseEnversEventL
auditProcess.addWorkUnit( auditProcess.addWorkUnit(
new CollectionChangeWorkUnit( new CollectionChangeWorkUnit(
event.getSession(), event.getSession(),
relatedEntityName, event.getSession().bestGuessEntityName(relatedObj),
getAuditConfiguration(), getAuditConfiguration(),
relatedId, relatedId,
relatedObj relatedObj

View File

@ -34,9 +34,11 @@ import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.envers.revisioninfo.RevisionInfoGenerator; import org.hibernate.envers.revisioninfo.RevisionInfoGenerator;
import org.hibernate.envers.synchronization.work.AuditWorkUnit; import org.hibernate.envers.synchronization.work.AuditWorkUnit;
import org.hibernate.envers.tools.Pair; import org.hibernate.envers.tools.Pair;
import org.hibernate.tuple.entity.EntityMetamodel;
/** /**
* @author Adam Warski (adam at warski dot org) * @author Adam Warski (adam at warski dot org)
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/ */
public class AuditProcess implements BeforeTransactionCompletionProcess { public class AuditProcess implements BeforeTransactionCompletionProcess {
private final RevisionInfoGenerator revisionInfoGenerator; private final RevisionInfoGenerator revisionInfoGenerator;
@ -78,9 +80,8 @@ public class AuditProcess implements BeforeTransactionCompletionProcess {
String entityName = vwu.getEntityName(); String entityName = vwu.getEntityName();
Pair<String, Object> usedIdsKey = Pair.make(entityName, entityId); Pair<String, Object> usedIdsKey = Pair.make(entityName, entityId);
if (usedIds.containsKey(usedIdsKey)) { AuditWorkUnit other = getAlreadyScheduledWorkUnit(usedIdsKey);
AuditWorkUnit other = usedIds.get(usedIdsKey); if (other != null) {
AuditWorkUnit result = vwu.dispatch(other); AuditWorkUnit result = vwu.dispatch(other);
if (result != other) { if (result != other) {
@ -99,6 +100,25 @@ public class AuditProcess implements BeforeTransactionCompletionProcess {
} }
} }
/**
* Checks if another work unit associated with the same entity hierarchy and identifier has already been scheduled.
* @param idKey Work unit's identifier.
* @return Corresponding work unit or {@code null} if no satisfying result was found.
*/
private AuditWorkUnit getAlreadyScheduledWorkUnit(Pair<String, Object> idKey) {
EntityMetamodel entityMetamodel = session.getFactory().getEntityPersister(idKey.getFirst()).getEntityMetamodel();
String rootEntityName = entityMetamodel.getRootName();
EntityMetamodel rootEntityMetamodel = session.getFactory().getEntityPersister(rootEntityName).getEntityMetamodel();
// Checking all possible subtypes, supertypes and the actual class.
for (Object entityName : rootEntityMetamodel.getSubclassEntityNames()) {
Pair<String, Object> key = Pair.make((String) entityName, idKey.getSecond());
if (usedIds.containsKey(key)) {
return usedIds.get(key);
}
}
return null;
}
private void executeInSession(Session session) { private void executeInSession(Session session) {
// Making sure the revision data is persisted. // Making sure the revision data is persisted.
Object currentRevisionData = getCurrentRevisionData(session, true); Object currentRevisionData = getCurrentRevisionData(session, true);

View File

@ -0,0 +1,155 @@
package org.hibernate.envers.test.integration.inheritance.joined.relation;
import org.hibernate.ejb.Ejb3Configuration;
import org.hibernate.envers.test.AbstractEntityTest;
import org.hibernate.envers.test.Priority;
import org.hibernate.envers.test.tools.TestTools;
import org.hibernate.testing.TestForIssue;
import org.junit.Assert;
import org.junit.Test;
import javax.persistence.EntityManager;
import java.util.Arrays;
/**
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/
@TestForIssue(jiraKey = "HHH-3843")
public class ParentReferencingChildTest extends AbstractEntityTest {
Person expLukaszRev1 = null;
Person expLukaszRev2 = null;
Person expAdamRev4 = null;
Role expDirectorRev3 = null;
Role expAdminRev2 = null;
Role expAdminRev1 = null;
public void configure(Ejb3Configuration cfg) {
cfg.addAnnotatedClass(Person.class);
cfg.addAnnotatedClass(Role.class);
cfg.addAnnotatedClass(RightsSubject.class);
}
@Test
@Priority(10)
public void initData() {
EntityManager em = getEntityManager();
// Revision 1
em.getTransaction().begin();
Person lukasz = new Person();
lukasz.setName("Lukasz");
lukasz.setGroup("IT");
em.persist(lukasz);
Role admin = new Role();
admin.setName("Admin");
admin.setGroup("Confidential");
lukasz.getRoles().add(admin);
admin.getMembers().add(lukasz);
em.persist(admin);
em.getTransaction().commit();
expLukaszRev1 = new Person(lukasz.getId(), "IT", "Lukasz");
expAdminRev1 = new Role(admin.getId(), "Confidential", "Admin");
// Revision 2
em.getTransaction().begin();
lukasz = em.find(Person.class, lukasz.getId());
lukasz.setGroup("Senior IT");
lukasz.setName("Lukasz Antoniak");
admin = em.find(Role.class, admin.getId());
admin.setGroup("Very Confidential");
em.getTransaction().commit();
expAdminRev2 = new Role(admin.getId(), "Very Confidential", "Admin");
expLukaszRev2 = new Person(lukasz.getId(), "Senior IT", "Lukasz Antoniak");
// Revision 3
em.getTransaction().begin();
lukasz = em.find(Person.class, lukasz.getId());
Role director = new Role();
director.setName("Director");
director.getMembers().add(lukasz);
em.persist(director);
lukasz.getRoles().add(director);
em.getTransaction().commit();
expDirectorRev3 = new Role(director.getId(), null, "Director");
// Revision 4
em.getTransaction().begin();
Person adam = new Person();
adam.setName("Adam");
adam.setGroup("CEO");
em.persist(adam);
director = em.find(Role.class, director.getId());
director.getMembers().add(adam);
adam.getRoles().add(director);
em.getTransaction().commit();
expAdamRev4 = new Person(adam.getId(), "CEO", "Adam");
// Revision 5
em.getTransaction().begin();
adam = em.find(Person.class, adam.getId());
admin = em.find(Role.class, admin.getId());
admin.getMembers().add(adam);
em.getTransaction().commit();
// Revision 6
em.getTransaction().begin();
adam = em.find(Person.class, adam.getId());
adam.setName("Adam Warski");
em.getTransaction().commit();
}
@Test
public void testRevisionsCounts() {
Assert.assertEquals(Arrays.asList(1, 2, 3), getAuditReader().getRevisions(Person.class, expLukaszRev1.getId()));
Assert.assertEquals(Arrays.asList(1, 2, 3), getAuditReader().getRevisions(RightsSubject.class, expLukaszRev1.getId()));
Assert.assertEquals(Arrays.asList(4, 5, 6), getAuditReader().getRevisions(Person.class, expAdamRev4.getId()));
Assert.assertEquals(Arrays.asList(4, 5, 6), getAuditReader().getRevisions(RightsSubject.class, expAdamRev4.getId()));
Assert.assertEquals(Arrays.asList(1, 2, 5), getAuditReader().getRevisions(Role.class, expAdminRev1.getId()));
Assert.assertEquals(Arrays.asList(1, 2, 5), getAuditReader().getRevisions(RightsSubject.class, expAdminRev1.getId()));
Assert.assertEquals(Arrays.asList(3, 4), getAuditReader().getRevisions(Role.class, expDirectorRev3.getId()));
Assert.assertEquals(Arrays.asList(3, 4), getAuditReader().getRevisions(RightsSubject.class, expDirectorRev3.getId()));
}
@Test
public void testHistoryOfAdam() {
Person adamRev4 = getAuditReader().find(Person.class, expAdamRev4.getId(), 4);
RightsSubject rightsSubjectRev5 = getAuditReader().find(RightsSubject.class, expAdamRev4.getId(), 5);
Assert.assertEquals(expAdamRev4, adamRev4);
Assert.assertEquals(TestTools.makeSet(expDirectorRev3), adamRev4.getRoles());
Assert.assertEquals(TestTools.makeSet(expDirectorRev3, expAdminRev2), rightsSubjectRev5.getRoles());
}
@Test
public void testHistoryOfLukasz() {
Person lukaszRev1 = getAuditReader().find(Person.class, expLukaszRev1.getId(), 1);
Person lukaszRev2 = getAuditReader().find(Person.class, expLukaszRev1.getId(), 2);
RightsSubject rightsSubjectRev3 = getAuditReader().find(RightsSubject.class, expLukaszRev1.getId(), 3);
Person lukaszRev3 = getAuditReader().find(Person.class, expLukaszRev1.getId(), 3);
Assert.assertEquals(expLukaszRev1, lukaszRev1);
Assert.assertEquals(expLukaszRev2, lukaszRev2);
Assert.assertEquals(TestTools.makeSet(expAdminRev1), lukaszRev1.getRoles());
Assert.assertEquals(TestTools.makeSet(expAdminRev2, expDirectorRev3), rightsSubjectRev3.getRoles());
Assert.assertEquals(TestTools.makeSet(expAdminRev2, expDirectorRev3), lukaszRev3.getRoles());
}
@Test
public void testHistoryOfAdmin() {
Role adminRev1 = getAuditReader().find(Role.class, expAdminRev1.getId(), 1);
Role adminRev2 = getAuditReader().find(Role.class, expAdminRev1.getId(), 2);
Role adminRev5 = getAuditReader().find(Role.class, expAdminRev1.getId(), 5);
Assert.assertEquals(expAdminRev1, adminRev1);
Assert.assertEquals(expAdminRev2, adminRev2);
Assert.assertEquals(TestTools.makeSet(expLukaszRev1), adminRev1.getMembers());
Assert.assertEquals(TestTools.makeSet(expLukaszRev2, expAdamRev4), adminRev5.getMembers());
}
}

View File

@ -0,0 +1,56 @@
package org.hibernate.envers.test.integration.inheritance.joined.relation;
import org.hibernate.envers.Audited;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/
@Entity
@Table(name = "APP_PERSON")
@Audited
public class Person extends RightsSubject {
private String name;
public Person() {
}
public Person(Long id, String group, String name) {
super(id, group);
this.name = name;
}
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Person)) return false;
if (!super.equals(o)) return false;
Person person = (Person) o;
if (name != null ? !name.equals(person.name) : person.name != null) return false;
return true;
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "Person(" + super.toString() + ", name = " + name + ")";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,94 @@
package org.hibernate.envers.test.integration.inheritance.joined.relation;
import org.hibernate.envers.Audited;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
/**
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/
@Entity
@Table(name = "APP_RIGHTSSUBJCT")
@Inheritance(strategy = InheritanceType.JOINED)
@Audited
public class RightsSubject {
@Id
@GeneratedValue
private Long id;
@Version
private Long version;
@Column(name = "APP_GROUP")
private String group;
@ManyToMany(mappedBy="members")
private Set<Role> roles = new HashSet<Role>();
public RightsSubject() {
}
public RightsSubject(Long id, String group) {
this.id = id;
this.group = group;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof RightsSubject)) return false;
RightsSubject that = (RightsSubject) o;
if (group != null ? !group.equals(that.group) : that.group != null) return false;
if (id != null ? !id.equals(that.id) : that.id != null) return false;
return true;
}
@Override
public int hashCode() {
int result = id != null ? id.hashCode() : 0;
result = 31 * result + (group != null ? group.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "RightsSubject(id = " + id + ", version = " + version + ", group = " + group + ")";
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getVersion() {
return version;
}
public void setVersion(Long version) {
this.version = version;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
}

View File

@ -0,0 +1,70 @@
package org.hibernate.envers.test.integration.inheritance.joined.relation;
import org.hibernate.envers.Audited;
import javax.persistence.Entity;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import java.util.HashSet;
import java.util.Set;
/**
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/
@Entity
@Table(name = "APP_ROLE")
@Audited
public class Role extends RightsSubject {
private String name;
@ManyToMany
private Set<RightsSubject> members = new HashSet<RightsSubject>();
public Role() {
}
public Role(Long id, String group, String name) {
super(id, group);
this.name = name;
}
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Role)) return false;
if (!super.equals(o)) return false;
Role role = (Role) o;
if (name != null ? !name.equals(role.name) : role.name != null) return false;
return true;
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "Role(" + super.toString() + ", name = " + name + ")";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<RightsSubject> getMembers() {
return members;
}
public void setMembers(Set<RightsSubject> members) {
this.members = members;
}
}