HHH-3843 - Fix and test
This commit is contained in:
parent
09d40d1785
commit
86482c630b
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue