HHH-7157 - Fix and test

This commit is contained in:
Lukasz Antoniak 2012-08-07 19:07:56 +02:00
parent d0e13b664a
commit 9aa88b9a24
7 changed files with 487 additions and 4 deletions

View File

@ -153,7 +153,7 @@ public final class CollectionMetadataGenerator {
boolean oneToManyAttachedType = type instanceof BagType || type instanceof SetType || type instanceof MapType || type instanceof ListType; boolean oneToManyAttachedType = type instanceof BagType || type instanceof SetType || type instanceof MapType || type instanceof ListType;
boolean inverseOneToMany = (value instanceof OneToMany) && (propertyValue.isInverse()); boolean inverseOneToMany = (value instanceof OneToMany) && (propertyValue.isInverse());
boolean owningManyToOneWithJoinTableBidirectional = (value instanceof ManyToOne) && (propertyAuditingData.getAuditMappedBy() != null); boolean owningManyToOneWithJoinTableBidirectional = (value instanceof ManyToOne) && (propertyAuditingData.getRelationMappedBy() != null);
boolean fakeOneToManyBidirectional = (value instanceof OneToMany) && (propertyAuditingData.getAuditMappedBy() != null); boolean fakeOneToManyBidirectional = (value instanceof OneToMany) && (propertyAuditingData.getAuditMappedBy() != null);
if (oneToManyAttachedType && (inverseOneToMany || fakeOneToManyBidirectional || owningManyToOneWithJoinTableBidirectional)) { if (oneToManyAttachedType && (inverseOneToMany || fakeOneToManyBidirectional || owningManyToOneWithJoinTableBidirectional)) {

View File

@ -410,8 +410,9 @@ public class AuditedPropertiesReader {
if (!processPropertyAuditingOverrides(property, propertyData)) { if (!processPropertyAuditingOverrides(property, propertyData)) {
return false; // not audited due to AuditOverride annotation return false; // not audited due to AuditOverride annotation
} }
addPropertyMapKey(property, propertyData); addPropertyMapKey(property, propertyData);
setPropertyAuditMappedBy(property, propertyData); setPropertyAuditMappedBy(property, propertyData);
setPropertyRelationMappedBy(property, propertyData);
return true; return true;
} }
@ -441,11 +442,14 @@ public class AuditedPropertiesReader {
globalCfg.isGlobalWithModifiedFlag() : aud.withModifiedFlag(); globalCfg.isGlobalWithModifiedFlag() : aud.withModifiedFlag();
} }
private void setPropertyAuditMappedBy(XProperty property, PropertyAuditingData propertyData) { private void setPropertyRelationMappedBy(XProperty property, PropertyAuditingData propertyData) {
OneToMany oneToMany = property.getAnnotation(OneToMany.class); OneToMany oneToMany = property.getAnnotation(OneToMany.class);
if (oneToMany != null && !"".equals(oneToMany.mappedBy())) { if (oneToMany != null && !"".equals(oneToMany.mappedBy())) {
propertyData.setAuditMappedBy(oneToMany.mappedBy()); propertyData.setRelationMappedBy(oneToMany.mappedBy());
} }
}
private void setPropertyAuditMappedBy(XProperty property, PropertyAuditingData propertyData) {
AuditMappedBy auditMappedBy = property.getAnnotation(AuditMappedBy.class); AuditMappedBy auditMappedBy = property.getAnnotation(AuditMappedBy.class);
if (auditMappedBy != null) { if (auditMappedBy != null) {
propertyData.setAuditMappedBy(auditMappedBy.mappedBy()); propertyData.setAuditMappedBy(auditMappedBy.mappedBy());

View File

@ -47,6 +47,7 @@ public class PropertyAuditingData {
private final List<AuditOverride> auditJoinTableOverrides = new ArrayList<AuditOverride>(0); private final List<AuditOverride> auditJoinTableOverrides = new ArrayList<AuditOverride>(0);
private RelationTargetAuditMode relationTargetAuditMode; private RelationTargetAuditMode relationTargetAuditMode;
private String auditMappedBy; private String auditMappedBy;
private String relationMappedBy;
private String positionMappedBy; private String positionMappedBy;
private boolean forceInsertable; private boolean forceInsertable;
private boolean usingModifiedFlag; private boolean usingModifiedFlag;
@ -134,6 +135,14 @@ public class PropertyAuditingData {
this.auditMappedBy = auditMappedBy; this.auditMappedBy = auditMappedBy;
} }
public String getRelationMappedBy() {
return relationMappedBy;
}
public void setRelationMappedBy(String relationMappedBy) {
this.relationMappedBy = relationMappedBy;
}
public String getPositionMappedBy() { public String getPositionMappedBy() {
return positionMappedBy; return positionMappedBy;
} }

View File

@ -0,0 +1,70 @@
package org.hibernate.envers.test.integration.onetomany.embeddedid;
import org.hibernate.envers.Audited;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import java.io.Serializable;
/**
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/
@Entity
@Audited
public class Constant implements Serializable {
@Id
@Column(length = 3)
private String id;
private String name;
public Constant() {
}
public Constant(String id, String name) {
this.id = id;
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Constant)) return false;
Constant constant = (Constant) o;
if (id != null ? !id.equals(constant.id) : constant.id != null) return false;
if (name != null ? !name.equals(constant.name) : constant.name != null) return false;
return true;
}
@Override
public int hashCode() {
int result = id != null ? id.hashCode() : 0;
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "Constant(id = " + id + ", name = " + name + ")";
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,130 @@
package org.hibernate.envers.test.integration.onetomany.embeddedid;
import javax.persistence.EntityManager;
import org.hibernate.envers.test.Priority;
import org.hibernate.testing.TestForIssue;
import org.junit.Assert;
import org.junit.Test;
import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
import java.util.Arrays;
/**
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/
@TestForIssue(jiraKey = "HHH-7157")
public class MapsIdTest extends BaseEnversJPAFunctionalTestCase {
private PersonTuple tuple1Ver1 = null;
private PersonTuple tuple2Ver1 = null;
private PersonTuple tuple2Ver2 = null;
private Person personCVer1 = null;
private Person personCVer2 = null;
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[]{Person.class, PersonTuple.class, Constant.class};
}
@Test
@Priority(10)
public void initData() {
EntityManager em = getEntityManager();
// Revision 1
em.getTransaction().begin();
Person personA = new Person("Peter");
Person personB = new Person("Mary");
em.persist(personA);
em.persist(personB);
Constant cons = new Constant("USD", "US Dollar");
em.persist(cons);
PersonTuple tuple1 = new PersonTuple(true, personA, personB, cons);
em.persist(tuple1);
em.getTransaction().commit();
tuple1Ver1 = new PersonTuple(tuple1.isHelloWorld(), tuple1.getPersonA(), tuple1.getPersonB(), tuple1.getConstant());
// Revision 2
em.getTransaction().begin();
cons = em.find(Constant.class, cons.getId());
Person personC1 = new Person("Lukasz");
em.persist(personC1);
PersonTuple tuple2 = new PersonTuple(true, personA, personC1, cons);
em.persist(tuple2);
em.getTransaction().commit();
tuple2Ver1 = new PersonTuple(tuple2.isHelloWorld(), tuple2.getPersonA(), tuple2.getPersonB(), tuple2.getConstant());
personCVer1 = new Person(personC1.getId(), personC1.getName());
personCVer1.getPersonBTuples().add(tuple2Ver1);
// Revision 3
em.getTransaction().begin();
tuple2 = em.find(PersonTuple.class, tuple2.getPersonTupleId());
tuple2.setHelloWorld(false);
em.merge(tuple2);
em.getTransaction().commit();
tuple2Ver2 = new PersonTuple(tuple2.isHelloWorld(), tuple2.getPersonA(), tuple2.getPersonB(), tuple2.getConstant());
// Revision 4
em.getTransaction().begin();
Person personC2 = em.find(Person.class, personC1.getId());
personC2.setName("Robert");
em.merge(personC2);
em.getTransaction().commit();
personCVer2 = new Person(personC2.getId(), personC2.getName());
personCVer2.getPersonBTuples().add(tuple2Ver1);
em.close();
}
@Test
public void testRevisionsCounts() {
Assert.assertEquals(Arrays.asList(1), getAuditReader().getRevisions(PersonTuple.class, tuple1Ver1.getPersonTupleId()));
Assert.assertEquals(Arrays.asList(2, 3), getAuditReader().getRevisions(PersonTuple.class, tuple2Ver1.getPersonTupleId()));
Assert.assertEquals(Arrays.asList(2, 4), getAuditReader().getRevisions(Person.class, personCVer1.getId()));
}
@Test
public void testHistoryOfTuple1() {
PersonTuple tuple = getAuditReader().find(PersonTuple.class, tuple1Ver1.getPersonTupleId(), 1);
Assert.assertEquals(tuple1Ver1, tuple);
Assert.assertEquals(tuple1Ver1.isHelloWorld(), tuple.isHelloWorld());
Assert.assertEquals(tuple1Ver1.getPersonA().getId(), tuple.getPersonA().getId());
Assert.assertEquals(tuple1Ver1.getPersonB().getId(), tuple.getPersonB().getId());
}
@Test
public void testHistoryOfTuple2() {
PersonTuple tuple = getAuditReader().find(PersonTuple.class, tuple2Ver2.getPersonTupleId(), 2);
Assert.assertEquals(tuple2Ver1, tuple);
Assert.assertEquals(tuple2Ver1.isHelloWorld(), tuple.isHelloWorld());
Assert.assertEquals(tuple2Ver1.getPersonA().getId(), tuple.getPersonA().getId());
Assert.assertEquals(tuple2Ver1.getPersonB().getId(), tuple.getPersonB().getId());
tuple = getAuditReader().find(PersonTuple.class, tuple2Ver2.getPersonTupleId(), 3);
Assert.assertEquals(tuple2Ver2, tuple);
Assert.assertEquals(tuple2Ver2.isHelloWorld(), tuple.isHelloWorld());
Assert.assertEquals(tuple2Ver2.getPersonA().getId(), tuple.getPersonA().getId());
Assert.assertEquals(tuple2Ver2.getPersonB().getId(), tuple.getPersonB().getId());
}
@Test
public void testHistoryOfPersonC() {
Person person = getAuditReader().find(Person.class, personCVer1.getId(), 2);
Assert.assertEquals(personCVer1, person);
Assert.assertEquals(personCVer1.getPersonATuples(), person.getPersonATuples());
Assert.assertEquals(personCVer1.getPersonBTuples(), person.getPersonBTuples());
person = getAuditReader().find(Person.class, personCVer2.getId(), 4);
Assert.assertEquals(personCVer2, person);
}
}

View File

@ -0,0 +1,96 @@
package org.hibernate.envers.test.integration.onetomany.embeddedid;
import org.hibernate.envers.Audited;
import javax.persistence.*;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
/**
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/
@Entity
@Audited
public class Person implements Serializable {
@Id
@GeneratedValue
private long id;
private String name;
@OneToMany(mappedBy = "personA")
private Set<PersonTuple> personATuples = new HashSet<PersonTuple>();
@OneToMany(mappedBy = "personB")
private Set<PersonTuple> personBTuples = new HashSet<PersonTuple>();
public Person() {
}
public Person(String name) {
this.name = name;
}
public Person(long id, String name) {
this.id = id;
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Person)) return false;
Person person = (Person) o;
if (id != person.id) return false;
if (name != null ? !name.equals(person.name) : person.name != null) return false;
return true;
}
@Override
public int hashCode() {
int result = (int) (id ^ (id >>> 32));
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "Person(id = " + id + ", name = " + name + ")";
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<PersonTuple> getPersonBTuples() {
return personBTuples;
}
public void setPersonBTuples(Set<PersonTuple> personBTuples) {
this.personBTuples = personBTuples;
}
public Set<PersonTuple> getPersonATuples() {
return personATuples;
}
public void setPersonATuples(Set<PersonTuple> personATuples) {
this.personATuples = personATuples;
}
}

View File

@ -0,0 +1,174 @@
package org.hibernate.envers.test.integration.onetomany.embeddedid;
import org.hibernate.envers.Audited;
import javax.persistence.*;
import java.io.Serializable;
/**
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/
@Entity
@Audited
public class PersonTuple implements Serializable {
@Embeddable
public static class PersonTupleId implements Serializable {
@Column(nullable = false)
private long personAId;
@Column(nullable = false)
private long personBId;
@Column(nullable = false)
private String constantId;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof PersonTupleId)) return false;
PersonTupleId that = (PersonTupleId) o;
if (personAId != that.personAId) return false;
if (personBId != that.personBId) return false;
if (constantId != null ? !constantId.equals(that.constantId) : that.constantId != null) return false;
return true;
}
@Override
public int hashCode() {
int result = (int) (personAId ^ (personAId >>> 32));
result = 31 * result + (int) (personBId ^ (personBId >>> 32));
result = 31 * result + (constantId != null ? constantId.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "PersonTupleId(personAId = " + personAId + ", personBId = " + personBId + ", constantId = " + constantId + ")";
}
public long getPersonAId() {
return personAId;
}
public void setPersonAId(long personAId) {
this.personAId = personAId;
}
public long getPersonBId() {
return personBId;
}
public void setPersonBId(long personBId) {
this.personBId = personBId;
}
public String getConstantId() {
return constantId;
}
public void setConstantId(String constantId) {
this.constantId = constantId;
}
}
@EmbeddedId
private PersonTupleId personTupleId = new PersonTupleId();
@MapsId("personAId")
@ManyToOne(optional = false)
@JoinColumn(insertable = false, updatable = false)
private Person personA;
@MapsId("personBId")
@ManyToOne(optional = false)
@JoinColumn(insertable = false, updatable = false)
private Person personB;
@MapsId("constantId")
@ManyToOne(optional = false)
@JoinColumn(insertable = false, updatable = false)
private Constant constant;
@Column(nullable = false)
private boolean helloWorld = false;
public PersonTuple() {
}
public PersonTuple(boolean helloWorld, Person personA, Person personB, Constant constant) {
this.helloWorld = helloWorld;
this.personA = personA;
this.personB = personB;
this.constant = constant;
this.personTupleId.personAId = personA.getId();
this.personTupleId.personBId = personB.getId();
this.personTupleId.constantId = constant.getId();
personA.getPersonATuples().add(this);
personB.getPersonBTuples().add(this);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof PersonTuple)) return false;
PersonTuple that = (PersonTuple) o;
return personTupleId.equals(that.personTupleId);
}
@Override
public int hashCode() {
return personTupleId.hashCode();
}
@Override
public String toString() {
return "PersonTuple(id = " + personTupleId + ", helloWorld = " + helloWorld + ")";
}
public PersonTupleId getPersonTupleId() {
return personTupleId;
}
public void setPersonTupleId(PersonTupleId personTupleId) {
this.personTupleId = personTupleId;
}
public Person getPersonA() {
return personA;
}
public void setPersonA(Person personA) {
this.personA = personA;
}
public Person getPersonB() {
return personB;
}
public void setPersonB(Person personB) {
this.personB = personB;
}
public Constant getConstant() {
return constant;
}
public void setConstant(Constant constant) {
this.constant = constant;
}
public boolean isHelloWorld() {
return helloWorld;
}
public void setHelloWorld(boolean helloWorld) {
this.helloWorld = helloWorld;
}
}