HHH-7157 - Fix and test
This commit is contained in:
parent
d0e13b664a
commit
9aa88b9a24
|
@ -153,7 +153,7 @@ public final class CollectionMetadataGenerator {
|
|||
|
||||
boolean oneToManyAttachedType = type instanceof BagType || type instanceof SetType || type instanceof MapType || type instanceof ListType;
|
||||
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);
|
||||
|
||||
if (oneToManyAttachedType && (inverseOneToMany || fakeOneToManyBidirectional || owningManyToOneWithJoinTableBidirectional)) {
|
||||
|
|
|
@ -412,6 +412,7 @@ public class AuditedPropertiesReader {
|
|||
}
|
||||
addPropertyMapKey(property, propertyData);
|
||||
setPropertyAuditMappedBy(property, propertyData);
|
||||
setPropertyRelationMappedBy(property, propertyData);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -441,11 +442,14 @@ public class AuditedPropertiesReader {
|
|||
globalCfg.isGlobalWithModifiedFlag() : aud.withModifiedFlag();
|
||||
}
|
||||
|
||||
private void setPropertyAuditMappedBy(XProperty property, PropertyAuditingData propertyData) {
|
||||
private void setPropertyRelationMappedBy(XProperty property, PropertyAuditingData propertyData) {
|
||||
OneToMany oneToMany = property.getAnnotation(OneToMany.class);
|
||||
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);
|
||||
if (auditMappedBy != null) {
|
||||
propertyData.setAuditMappedBy(auditMappedBy.mappedBy());
|
||||
|
|
|
@ -47,6 +47,7 @@ public class PropertyAuditingData {
|
|||
private final List<AuditOverride> auditJoinTableOverrides = new ArrayList<AuditOverride>(0);
|
||||
private RelationTargetAuditMode relationTargetAuditMode;
|
||||
private String auditMappedBy;
|
||||
private String relationMappedBy;
|
||||
private String positionMappedBy;
|
||||
private boolean forceInsertable;
|
||||
private boolean usingModifiedFlag;
|
||||
|
@ -134,6 +135,14 @@ public class PropertyAuditingData {
|
|||
this.auditMappedBy = auditMappedBy;
|
||||
}
|
||||
|
||||
public String getRelationMappedBy() {
|
||||
return relationMappedBy;
|
||||
}
|
||||
|
||||
public void setRelationMappedBy(String relationMappedBy) {
|
||||
this.relationMappedBy = relationMappedBy;
|
||||
}
|
||||
|
||||
public String getPositionMappedBy() {
|
||||
return positionMappedBy;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue