diff --git a/envers/pom.xml b/envers/pom.xml
index 1cf776af19..e2fdba12e2 100644
--- a/envers/pom.xml
+++ b/envers/pom.xml
@@ -95,14 +95,14 @@
org.testng
testng
- 5.10
+ 5.8
jdk15
test
com.h2database
h2
- 1.0.79
+ 1.2.125
test
diff --git a/envers/src/main/java/org/hibernate/envers/event/AuditEventListener.java b/envers/src/main/java/org/hibernate/envers/event/AuditEventListener.java
index 670b66aa88..ee70e5f938 100644
--- a/envers/src/main/java/org/hibernate/envers/event/AuditEventListener.java
+++ b/envers/src/main/java/org/hibernate/envers/event/AuditEventListener.java
@@ -229,7 +229,7 @@ public class AuditEventListener implements PostInsertEventListener, PostUpdateEv
relatedId, relatedObj);
verSync.addWorkUnit(new FakeBidirectionalRelationWorkUnit(event.getSession(), relatedEntityName, verCfg,
- relatedId, event.getAffectedOwnerOrNull(), rd, revType, nestedWorkUnit));
+ relatedId, referencingPropertyName, event.getAffectedOwnerOrNull(), rd, revType, nestedWorkUnit));
}
// We also have to generate a collection change work unit for the owning entity.
diff --git a/envers/src/main/java/org/hibernate/envers/synchronization/work/FakeBidirectionalRelationWorkUnit.java b/envers/src/main/java/org/hibernate/envers/synchronization/work/FakeBidirectionalRelationWorkUnit.java
index 9714c7c979..13b1e09e0e 100644
--- a/envers/src/main/java/org/hibernate/envers/synchronization/work/FakeBidirectionalRelationWorkUnit.java
+++ b/envers/src/main/java/org/hibernate/envers/synchronization/work/FakeBidirectionalRelationWorkUnit.java
@@ -8,6 +8,8 @@ import org.hibernate.envers.RevisionType;
import java.io.Serializable;
import java.util.Map;
import java.util.HashMap;
+import java.util.Set;
+import java.util.HashSet;
/**
* A work unit that handles "fake" bidirectional one-to-many relations (mapped with {@code @OneToMany+@JoinColumn} and
@@ -15,44 +17,49 @@ import java.util.HashMap;
* @author Adam Warski (adam at warski dot org)
*/
public class FakeBidirectionalRelationWorkUnit extends AbstractAuditWorkUnit implements AuditWorkUnit {
- private final Object owningEntity;
- private final RelationDescription rd;
- private final RevisionType revisionType;
+ private final Map fakeRelationChanges;
/*
* The work unit responsible for generating the "raw" entity data to be saved.
*/
private final AuditWorkUnit nestedWorkUnit;
-
public FakeBidirectionalRelationWorkUnit(SessionImplementor sessionImplementor, String entityName,
- AuditConfiguration verCfg, Serializable id, Object owningEntity,
+ AuditConfiguration verCfg, Serializable id,
+ String referencingPropertyName, Object owningEntity,
RelationDescription rd, RevisionType revisionType,
AuditWorkUnit nestedWorkUnit) {
super(sessionImplementor, entityName, verCfg, id);
+ this.nestedWorkUnit = nestedWorkUnit;
+ // Adding the change for the relation.
+ fakeRelationChanges = new HashMap();
+ fakeRelationChanges.put(referencingPropertyName, new FakeRelationChange(owningEntity, rd, revisionType));
+ }
- this.owningEntity = owningEntity;
- this.rd = rd;
- this.revisionType = revisionType;
+ public FakeBidirectionalRelationWorkUnit(FakeBidirectionalRelationWorkUnit original,
+ Map fakeRelationChanges,
+ AuditWorkUnit nestedWorkUnit) {
+ super(original.sessionImplementor, original.entityName, original.verCfg, original.id);
+
+ this.fakeRelationChanges = fakeRelationChanges;
this.nestedWorkUnit = nestedWorkUnit;
}
public FakeBidirectionalRelationWorkUnit(FakeBidirectionalRelationWorkUnit original, AuditWorkUnit nestedWorkUnit) {
super(original.sessionImplementor, original.entityName, original.verCfg, original.id);
- this.owningEntity = original.owningEntity;
- this.rd = original.rd;
- this.revisionType = original.revisionType;
this.nestedWorkUnit = nestedWorkUnit;
+
+ fakeRelationChanges = new HashMap(original.getFakeRelationChanges());
}
public AuditWorkUnit getNestedWorkUnit() {
return nestedWorkUnit;
}
- public RevisionType getRevisionType() {
- return revisionType;
+ public Map getFakeRelationChanges() {
+ return fakeRelationChanges;
}
public boolean containsWork() {
@@ -64,11 +71,10 @@ public class FakeBidirectionalRelationWorkUnit extends AbstractAuditWorkUnit imp
// Making a defensive copy not to modify the data held by the nested work unit.
Map nestedData = new HashMap(nestedWorkUnit.generateData(revisionData));
- // Now adding data for the fake relation.
- // If the revision type is "DEL", it means that the object is removed from the collection. Then the
- // new owner will in fact be null.
- rd.getFakeBidirectionalRelationMapper().mapToMapFromEntity(sessionImplementor, nestedData,
- revisionType == RevisionType.DEL ? null : owningEntity, null);
+ // Now adding data for all fake relations.
+ for (FakeRelationChange fakeRelationChange : fakeRelationChanges.values()) {
+ fakeRelationChange.generateData(sessionImplementor, nestedData);
+ }
return nestedData;
}
@@ -90,19 +96,23 @@ public class FakeBidirectionalRelationWorkUnit extends AbstractAuditWorkUnit imp
}
public AuditWorkUnit merge(FakeBidirectionalRelationWorkUnit second) {
- /*
- * The merging rules are the following (revision types of the first and second work units):
- * - DEL, DEL - return any (the work units are the same)
- * - DEL, ADD - return ADD (points to new owner)
- * - ADD, DEL - return ADD (points to new owner)
- * - ADD, ADD - return second (points to newer owner)
- */
+ // First merging the nested work units.
+ AuditWorkUnit mergedNested = second.getNestedWorkUnit().dispatch(nestedWorkUnit);
- if (revisionType == RevisionType.DEL || second.getRevisionType() == RevisionType.ADD) {
- return second;
+ // Now merging the fake relation changes from both work units.
+ Map secondFakeRelationChanges = second.getFakeRelationChanges();
+ Map mergedFakeRelationChanges = new HashMap();
+ Set allPropertyNames = new HashSet(fakeRelationChanges.keySet());
+ allPropertyNames.addAll(secondFakeRelationChanges.keySet());
+
+ for (String propertyName : allPropertyNames) {
+ mergedFakeRelationChanges.put(propertyName,
+ FakeRelationChange.merge(
+ fakeRelationChanges.get(propertyName),
+ secondFakeRelationChanges.get(propertyName)));
}
- return this;
+ return new FakeBidirectionalRelationWorkUnit(this, mergedFakeRelationChanges, mergedNested);
}
public AuditWorkUnit dispatch(WorkUnitMergeVisitor first) {
@@ -116,4 +126,48 @@ public class FakeBidirectionalRelationWorkUnit extends AbstractAuditWorkUnit imp
// Creating a new fake relation work unit with the nested merged data
return new FakeBidirectionalRelationWorkUnit(frwu, nestedMerged);
}
+
+ /**
+ * Describes a change to a single fake bidirectional relation.
+ */
+ private static class FakeRelationChange {
+ private final Object owningEntity;
+ private final RelationDescription rd;
+ private final RevisionType revisionType;
+
+ public FakeRelationChange(Object owningEntity, RelationDescription rd, RevisionType revisionType) {
+ this.owningEntity = owningEntity;
+ this.rd = rd;
+ this.revisionType = revisionType;
+ }
+
+ public RevisionType getRevisionType() {
+ return revisionType;
+ }
+
+ public void generateData(SessionImplementor sessionImplementor, Map data) {
+ // If the revision type is "DEL", it means that the object is removed from the collection. Then the
+ // new owner will in fact be null.
+ rd.getFakeBidirectionalRelationMapper().mapToMapFromEntity(sessionImplementor, data,
+ revisionType == RevisionType.DEL ? null : owningEntity, null);
+ }
+
+ public static FakeRelationChange merge(FakeRelationChange first, FakeRelationChange second) {
+ if (first == null) { return second; }
+ if (second == null) { return first; }
+
+ /*
+ * The merging rules are the following (revision types of the first and second changes):
+ * - DEL, DEL - return any (the work units are the same)
+ * - DEL, ADD - return ADD (points to new owner)
+ * - ADD, DEL - return ADD (points to new owner)
+ * - ADD, ADD - return second (points to newer owner)
+ */
+ if (first.getRevisionType() == RevisionType.DEL || second.getRevisionType() == RevisionType.ADD) {
+ return second;
+ } else {
+ return first;
+ }
+ }
+ }
}
diff --git a/envers/src/test/java/org/hibernate/envers/test/entities/onetomany/detached/DoubleListJoinColumnBidirectionalRefEdEntity1.java b/envers/src/test/java/org/hibernate/envers/test/entities/onetomany/detached/DoubleListJoinColumnBidirectionalRefEdEntity1.java
new file mode 100644
index 0000000000..5943295ee7
--- /dev/null
+++ b/envers/src/test/java/org/hibernate/envers/test/entities/onetomany/detached/DoubleListJoinColumnBidirectionalRefEdEntity1.java
@@ -0,0 +1,85 @@
+package org.hibernate.envers.test.entities.onetomany.detached;
+
+import org.hibernate.envers.Audited;
+
+import javax.persistence.*;
+
+/**
+ * Entity for {@link org.hibernate.envers.test.integration.onetomany.detached.DoubleJoinColumnBidirectionalList} test.
+ * Owned side of the first relation.
+ * @author Adam Warski (adam at warski dot org)
+ */
+@Entity
+@Audited
+public class DoubleListJoinColumnBidirectionalRefEdEntity1 {
+ @Id
+ @GeneratedValue
+ private Integer id;
+
+ private String data;
+
+ @ManyToOne
+ @JoinColumn(name = "some_join_column_1", insertable = false, updatable = false)
+ private DoubleListJoinColumnBidirectionalRefIngEntity owner;
+
+ public DoubleListJoinColumnBidirectionalRefEdEntity1() { }
+
+ public DoubleListJoinColumnBidirectionalRefEdEntity1(Integer id, String data, DoubleListJoinColumnBidirectionalRefIngEntity owner) {
+ this.id = id;
+ this.data = data;
+ this.owner = owner;
+ }
+
+ public DoubleListJoinColumnBidirectionalRefEdEntity1(String data, DoubleListJoinColumnBidirectionalRefIngEntity owner) {
+ this.data = data;
+ this.owner = owner;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public DoubleListJoinColumnBidirectionalRefIngEntity getOwner() {
+ return owner;
+ }
+
+ public void setOwner(DoubleListJoinColumnBidirectionalRefIngEntity owner) {
+ this.owner = owner;
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof DoubleListJoinColumnBidirectionalRefEdEntity1)) return false;
+
+ DoubleListJoinColumnBidirectionalRefEdEntity1 that = (DoubleListJoinColumnBidirectionalRefEdEntity1) o;
+
+ if (data != null ? !data.equals(that.data) : that.data != null) return false;
+ //noinspection RedundantIfStatement
+ if (id != null ? !id.equals(that.id) : that.id != null) return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = (id != null ? id.hashCode() : 0);
+ result = 31 * result + (data != null ? data.hashCode() : 0);
+ return result;
+ }
+
+ public String toString() {
+ return "DoubleListJoinColumnBidirectionalRefIngEntity1(id = " + id + ", data = " + data + ")";
+ }
+}
\ No newline at end of file
diff --git a/envers/src/test/java/org/hibernate/envers/test/entities/onetomany/detached/DoubleListJoinColumnBidirectionalRefEdEntity2.java b/envers/src/test/java/org/hibernate/envers/test/entities/onetomany/detached/DoubleListJoinColumnBidirectionalRefEdEntity2.java
new file mode 100644
index 0000000000..a7ede51dc5
--- /dev/null
+++ b/envers/src/test/java/org/hibernate/envers/test/entities/onetomany/detached/DoubleListJoinColumnBidirectionalRefEdEntity2.java
@@ -0,0 +1,85 @@
+package org.hibernate.envers.test.entities.onetomany.detached;
+
+import org.hibernate.envers.Audited;
+
+import javax.persistence.*;
+
+/**
+ * Entity for {@link org.hibernate.envers.test.integration.onetomany.detached.DoubleJoinColumnBidirectionalList} test.
+ * Owned side of the second relation.
+ * @author Adam Warski (adam at warski dot org)
+ */
+@Entity
+@Audited
+public class DoubleListJoinColumnBidirectionalRefEdEntity2 {
+ @Id
+ @GeneratedValue
+ private Integer id;
+
+ private String data;
+
+ @ManyToOne
+ @JoinColumn(name = "some_join_column_2", insertable = false, updatable = false)
+ private DoubleListJoinColumnBidirectionalRefIngEntity owner;
+
+ public DoubleListJoinColumnBidirectionalRefEdEntity2() { }
+
+ public DoubleListJoinColumnBidirectionalRefEdEntity2(Integer id, String data, DoubleListJoinColumnBidirectionalRefIngEntity owner) {
+ this.id = id;
+ this.data = data;
+ this.owner = owner;
+ }
+
+ public DoubleListJoinColumnBidirectionalRefEdEntity2(String data, DoubleListJoinColumnBidirectionalRefIngEntity owner) {
+ this.data = data;
+ this.owner = owner;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public DoubleListJoinColumnBidirectionalRefIngEntity getOwner() {
+ return owner;
+ }
+
+ public void setOwner(DoubleListJoinColumnBidirectionalRefIngEntity owner) {
+ this.owner = owner;
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof DoubleListJoinColumnBidirectionalRefEdEntity2)) return false;
+
+ DoubleListJoinColumnBidirectionalRefEdEntity2 that = (DoubleListJoinColumnBidirectionalRefEdEntity2) o;
+
+ if (data != null ? !data.equals(that.data) : that.data != null) return false;
+ //noinspection RedundantIfStatement
+ if (id != null ? !id.equals(that.id) : that.id != null) return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = (id != null ? id.hashCode() : 0);
+ result = 31 * result + (data != null ? data.hashCode() : 0);
+ return result;
+ }
+
+ public String toString() {
+ return "DoubleListJoinColumnBidirectionalRefIngEntity2(id = " + id + ", data = " + data + ")";
+ }
+}
\ No newline at end of file
diff --git a/envers/src/test/java/org/hibernate/envers/test/entities/onetomany/detached/DoubleListJoinColumnBidirectionalRefIngEntity.java b/envers/src/test/java/org/hibernate/envers/test/entities/onetomany/detached/DoubleListJoinColumnBidirectionalRefIngEntity.java
new file mode 100644
index 0000000000..7553f0447f
--- /dev/null
+++ b/envers/src/test/java/org/hibernate/envers/test/entities/onetomany/detached/DoubleListJoinColumnBidirectionalRefIngEntity.java
@@ -0,0 +1,100 @@
+package org.hibernate.envers.test.entities.onetomany.detached;
+
+import org.hibernate.envers.AuditMappedBy;
+import org.hibernate.envers.Audited;
+
+import javax.persistence.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Entity for {@link org.hibernate.envers.test.integration.onetomany.detached.DoubleJoinColumnBidirectionalList} test.
+ * Owning side of the relations.
+ * @author Adam Warski (adam at warski dot org)
+ */
+@Entity
+@Audited
+public class DoubleListJoinColumnBidirectionalRefIngEntity {
+ @Id
+ @GeneratedValue
+ private Integer id;
+
+ private String data;
+
+ @OneToMany
+ @JoinColumn(name = "some_join_column_1")
+ @AuditMappedBy(mappedBy = "owner")
+ private List references1 = new ArrayList();
+
+ @OneToMany
+ @JoinColumn(name = "some_join_column_2")
+ @AuditMappedBy(mappedBy = "owner")
+ private List references2 = new ArrayList();
+
+ public DoubleListJoinColumnBidirectionalRefIngEntity() { }
+
+ public DoubleListJoinColumnBidirectionalRefIngEntity(Integer id, String data) {
+ this.id = id;
+ this.data = data;
+ }
+
+ public DoubleListJoinColumnBidirectionalRefIngEntity(String data) {
+ this(null, data);
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public List getReferences1() {
+ return references1;
+ }
+
+ public void setReferences1(List references1) {
+ this.references1 = references1;
+ }
+
+ public List getReferences2() {
+ return references2;
+ }
+
+ public void setReferences2(List references2) {
+ this.references2 = references2;
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof DoubleListJoinColumnBidirectionalRefIngEntity)) return false;
+
+ DoubleListJoinColumnBidirectionalRefIngEntity that = (DoubleListJoinColumnBidirectionalRefIngEntity) o;
+
+ if (data != null ? !data.equals(that.data) : that.data != null) return false;
+ //noinspection RedundantIfStatement
+ if (id != null ? !id.equals(that.id) : that.id != null) return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = (id != null ? id.hashCode() : 0);
+ result = 31 * result + (data != null ? data.hashCode() : 0);
+ return result;
+ }
+
+ public String toString() {
+ return "DoubleListJoinColumnBidirectionalRefIngEntity(id = " + id + ", data = " + data + ")";
+ }
+}
\ No newline at end of file
diff --git a/envers/src/test/java/org/hibernate/envers/test/integration/onetomany/detached/DoubleJoinColumnBidirectionalList.java b/envers/src/test/java/org/hibernate/envers/test/integration/onetomany/detached/DoubleJoinColumnBidirectionalList.java
new file mode 100644
index 0000000000..6d02629ce6
--- /dev/null
+++ b/envers/src/test/java/org/hibernate/envers/test/integration/onetomany/detached/DoubleJoinColumnBidirectionalList.java
@@ -0,0 +1,299 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.integration.onetomany.detached;
+
+import org.hibernate.ejb.Ejb3Configuration;
+import org.hibernate.envers.test.AbstractEntityTest;
+import org.hibernate.envers.test.entities.onetomany.detached.DoubleListJoinColumnBidirectionalRefEdEntity1;
+import org.hibernate.envers.test.entities.onetomany.detached.DoubleListJoinColumnBidirectionalRefEdEntity2;
+import org.hibernate.envers.test.entities.onetomany.detached.DoubleListJoinColumnBidirectionalRefIngEntity;
+import static org.hibernate.envers.test.tools.TestTools.checkList;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import org.testng.annotations.Test;
+
+import javax.persistence.EntityManager;
+import java.util.Arrays;
+
+/**
+ * Test for a double "fake" bidirectional mapping where one side uses @OneToMany+@JoinColumn
+ * (and thus owns the relation), and the other uses a @ManyToOne(insertable=false, updatable=false).
+ * @author Adam Warski (adam at warski dot org)
+ */
+public class DoubleJoinColumnBidirectionalList extends AbstractEntityTest {
+ private Integer ed1_1_id;
+ private Integer ed2_1_id;
+ private Integer ed1_2_id;
+ private Integer ed2_2_id;
+
+ private Integer ing1_id;
+ private Integer ing2_id;
+
+ public void configure(Ejb3Configuration cfg) {
+ cfg.addAnnotatedClass(DoubleListJoinColumnBidirectionalRefIngEntity.class);
+ cfg.addAnnotatedClass(DoubleListJoinColumnBidirectionalRefEdEntity1.class);
+ cfg.addAnnotatedClass(DoubleListJoinColumnBidirectionalRefEdEntity2.class);
+ }
+
+ @Test(enabled = true)
+ public void createData() {
+ EntityManager em = getEntityManager();
+
+ DoubleListJoinColumnBidirectionalRefEdEntity1 ed1_1 = new DoubleListJoinColumnBidirectionalRefEdEntity1("ed1_1", null);
+ DoubleListJoinColumnBidirectionalRefEdEntity1 ed1_2 = new DoubleListJoinColumnBidirectionalRefEdEntity1("ed1_2", null);
+
+ DoubleListJoinColumnBidirectionalRefEdEntity2 ed2_1 = new DoubleListJoinColumnBidirectionalRefEdEntity2("ed2_1", null);
+ DoubleListJoinColumnBidirectionalRefEdEntity2 ed2_2 = new DoubleListJoinColumnBidirectionalRefEdEntity2("ed2_2", null);
+
+ DoubleListJoinColumnBidirectionalRefIngEntity ing1 = new DoubleListJoinColumnBidirectionalRefIngEntity("coll1");
+ DoubleListJoinColumnBidirectionalRefIngEntity ing2 = new DoubleListJoinColumnBidirectionalRefIngEntity("coll2");
+
+ // Revision 1 (ing1: ed1_1, ed2_1, ing2: ed1_2, ed2_2)
+ em.getTransaction().begin();
+
+ ing1.getReferences1().add(ed1_1);
+ ing1.getReferences2().add(ed2_1);
+
+ ing2.getReferences1().add(ed1_2);
+ ing2.getReferences2().add(ed2_2);
+
+ em.persist(ed1_1);
+ em.persist(ed1_2);
+ em.persist(ed2_1);
+ em.persist(ed2_2);
+ em.persist(ing1);
+ em.persist(ing2);
+
+ em.getTransaction().commit();
+
+ // Revision 2 (ing1: ed1_1, ed1_2, ed2_1, ed2_2)
+ em.getTransaction().begin();
+
+ ing1 = em.find(DoubleListJoinColumnBidirectionalRefIngEntity.class, ing1.getId());
+ ing2 = em.find(DoubleListJoinColumnBidirectionalRefIngEntity.class, ing2.getId());
+ ed1_1 = em.find(DoubleListJoinColumnBidirectionalRefEdEntity1.class, ed1_1.getId());
+ ed1_2 = em.find(DoubleListJoinColumnBidirectionalRefEdEntity1.class, ed1_2.getId());
+ ed2_1 = em.find(DoubleListJoinColumnBidirectionalRefEdEntity2.class, ed2_1.getId());
+ ed2_2 = em.find(DoubleListJoinColumnBidirectionalRefEdEntity2.class, ed2_2.getId());
+
+ ing2.getReferences1().clear();
+ ing2.getReferences2().clear();
+
+ ing1.getReferences1().add(ed1_2);
+ ing1.getReferences2().add(ed2_2);
+
+ em.getTransaction().commit();
+ em.clear();
+
+ // Revision 3 (ing1: ed1_1, ed1_2, ed2_1, ed2_2)
+ em.getTransaction().begin();
+
+ ing1 = em.find(DoubleListJoinColumnBidirectionalRefIngEntity.class, ing1.getId());
+ ing2 = em.find(DoubleListJoinColumnBidirectionalRefIngEntity.class, ing2.getId());
+ ed1_1 = em.find(DoubleListJoinColumnBidirectionalRefEdEntity1.class, ed1_1.getId());
+ ed1_2 = em.find(DoubleListJoinColumnBidirectionalRefEdEntity1.class, ed1_2.getId());
+ ed2_1 = em.find(DoubleListJoinColumnBidirectionalRefEdEntity2.class, ed2_1.getId());
+ ed2_2 = em.find(DoubleListJoinColumnBidirectionalRefEdEntity2.class, ed2_2.getId());
+
+ ed1_1.setData("ed1_1 bis");
+ ed2_2.setData("ed2_2 bis");
+
+ em.getTransaction().commit();
+ em.clear();
+
+ // Revision 4 (ing1: ed2_2, ing2: ed2_1, ed1_1, ed1_2)
+ em.getTransaction().begin();
+
+ ing1 = em.find(DoubleListJoinColumnBidirectionalRefIngEntity.class, ing1.getId());
+ ing2 = em.find(DoubleListJoinColumnBidirectionalRefIngEntity.class, ing2.getId());
+ ed1_1 = em.find(DoubleListJoinColumnBidirectionalRefEdEntity1.class, ed1_1.getId());
+ ed1_2 = em.find(DoubleListJoinColumnBidirectionalRefEdEntity1.class, ed1_2.getId());
+ ed2_1 = em.find(DoubleListJoinColumnBidirectionalRefEdEntity2.class, ed2_1.getId());
+ ed2_2 = em.find(DoubleListJoinColumnBidirectionalRefEdEntity2.class, ed2_2.getId());
+
+ ing1.getReferences1().clear();
+ ing2.getReferences1().add(ed1_1);
+ ing2.getReferences1().add(ed1_2);
+
+ ing1.getReferences2().remove(ed2_1);
+ ing2.getReferences2().add(ed2_1);
+
+ em.getTransaction().commit();
+ em.clear();
+
+ //
+
+ ing1_id = ing1.getId();
+ ing2_id = ing2.getId();
+
+ ed1_1_id = ed1_1.getId();
+ ed1_2_id = ed1_2.getId();
+ ed2_1_id = ed2_1.getId();
+ ed2_2_id = ed2_2.getId();
+ }
+
+ @Test(enabled = true, dependsOnMethods = "createData")
+ public void testRevisionsCounts() {
+ assertEquals(Arrays.asList(1, 2, 4), getAuditReader().getRevisions(DoubleListJoinColumnBidirectionalRefIngEntity.class, ing1_id));
+ assertEquals(Arrays.asList(1, 2, 4), getAuditReader().getRevisions(DoubleListJoinColumnBidirectionalRefIngEntity.class, ing2_id));
+
+ assertEquals(Arrays.asList(1, 3, 4), getAuditReader().getRevisions(DoubleListJoinColumnBidirectionalRefEdEntity1.class, ed1_1_id));
+ assertEquals(Arrays.asList(1, 2, 4), getAuditReader().getRevisions(DoubleListJoinColumnBidirectionalRefEdEntity1.class, ed1_2_id));
+
+ assertEquals(Arrays.asList(1, 4), getAuditReader().getRevisions(DoubleListJoinColumnBidirectionalRefEdEntity2.class, ed2_1_id));
+ assertEquals(Arrays.asList(1, 2, 3), getAuditReader().getRevisions(DoubleListJoinColumnBidirectionalRefEdEntity2.class, ed2_2_id));
+ }
+
+ @Test(enabled = true, dependsOnMethods = "createData")
+ public void testHistoryOfIng1() {
+ DoubleListJoinColumnBidirectionalRefEdEntity1 ed1_1_fromRev1 = new DoubleListJoinColumnBidirectionalRefEdEntity1(ed1_1_id, "ed1_1", null);
+ DoubleListJoinColumnBidirectionalRefEdEntity1 ed1_1_fromRev3 = new DoubleListJoinColumnBidirectionalRefEdEntity1(ed1_1_id, "ed1_1 bis", null);
+ DoubleListJoinColumnBidirectionalRefEdEntity1 ed1_2 = getEntityManager().find(DoubleListJoinColumnBidirectionalRefEdEntity1.class, ed1_2_id);
+ DoubleListJoinColumnBidirectionalRefEdEntity2 ed2_1 = getEntityManager().find(DoubleListJoinColumnBidirectionalRefEdEntity2.class, ed2_1_id);
+ DoubleListJoinColumnBidirectionalRefEdEntity2 ed2_2_fromRev1 = new DoubleListJoinColumnBidirectionalRefEdEntity2(ed2_2_id, "ed2_2", null);
+ DoubleListJoinColumnBidirectionalRefEdEntity2 ed2_2_fromRev3 = new DoubleListJoinColumnBidirectionalRefEdEntity2(ed2_2_id, "ed2_2 bis", null);
+
+ DoubleListJoinColumnBidirectionalRefIngEntity rev1 = getAuditReader().find(DoubleListJoinColumnBidirectionalRefIngEntity.class, ing1_id, 1);
+ DoubleListJoinColumnBidirectionalRefIngEntity rev2 = getAuditReader().find(DoubleListJoinColumnBidirectionalRefIngEntity.class, ing1_id, 2);
+ DoubleListJoinColumnBidirectionalRefIngEntity rev3 = getAuditReader().find(DoubleListJoinColumnBidirectionalRefIngEntity.class, ing1_id, 3);
+ DoubleListJoinColumnBidirectionalRefIngEntity rev4 = getAuditReader().find(DoubleListJoinColumnBidirectionalRefIngEntity.class, ing1_id, 4);
+
+ assertTrue(checkList(rev1.getReferences1(), ed1_1_fromRev1));
+ assertTrue(checkList(rev2.getReferences1(), ed1_1_fromRev1, ed1_2));
+ assertTrue(checkList(rev3.getReferences1(), ed1_1_fromRev3, ed1_2));
+ assertTrue(checkList(rev4.getReferences1()));
+
+ assertTrue(checkList(rev1.getReferences2(), ed2_1));
+ assertTrue(checkList(rev2.getReferences2(), ed2_1, ed2_2_fromRev1));
+ assertTrue(checkList(rev3.getReferences2(), ed2_1, ed2_2_fromRev3));
+ assertTrue(checkList(rev4.getReferences2(), ed2_2_fromRev3));
+ }
+
+ @Test(enabled = true, dependsOnMethods = "createData")
+ public void testHistoryOfIng2() {
+ DoubleListJoinColumnBidirectionalRefEdEntity1 ed1_1_fromRev3 = new DoubleListJoinColumnBidirectionalRefEdEntity1(ed1_1_id, "ed1_1 bis", null);
+ DoubleListJoinColumnBidirectionalRefEdEntity1 ed1_2 = getEntityManager().find(DoubleListJoinColumnBidirectionalRefEdEntity1.class, ed1_2_id);
+ DoubleListJoinColumnBidirectionalRefEdEntity2 ed2_1 = getEntityManager().find(DoubleListJoinColumnBidirectionalRefEdEntity2.class, ed2_1_id);
+ DoubleListJoinColumnBidirectionalRefEdEntity2 ed2_2_fromRev1 = new DoubleListJoinColumnBidirectionalRefEdEntity2(ed2_2_id, "ed2_2", null);
+
+ DoubleListJoinColumnBidirectionalRefIngEntity rev1 = getAuditReader().find(DoubleListJoinColumnBidirectionalRefIngEntity.class, ing2_id, 1);
+ DoubleListJoinColumnBidirectionalRefIngEntity rev2 = getAuditReader().find(DoubleListJoinColumnBidirectionalRefIngEntity.class, ing2_id, 2);
+ DoubleListJoinColumnBidirectionalRefIngEntity rev3 = getAuditReader().find(DoubleListJoinColumnBidirectionalRefIngEntity.class, ing2_id, 3);
+ DoubleListJoinColumnBidirectionalRefIngEntity rev4 = getAuditReader().find(DoubleListJoinColumnBidirectionalRefIngEntity.class, ing2_id, 4);
+
+ assertTrue(checkList(rev1.getReferences1(), ed1_2));
+ assertTrue(checkList(rev2.getReferences1()));
+ assertTrue(checkList(rev3.getReferences1()));
+ assertTrue(checkList(rev4.getReferences1(), ed1_1_fromRev3, ed1_2));
+
+ assertTrue(checkList(rev1.getReferences2(), ed2_2_fromRev1));
+ assertTrue(checkList(rev2.getReferences2()));
+ assertTrue(checkList(rev3.getReferences2()));
+ assertTrue(checkList(rev4.getReferences2(), ed2_1));
+ }
+
+ @Test(enabled = true, dependsOnMethods = "createData")
+ public void testHistoryOfEd1_1() {
+ DoubleListJoinColumnBidirectionalRefIngEntity ing1 = getEntityManager().find(DoubleListJoinColumnBidirectionalRefIngEntity.class, ing1_id);
+ DoubleListJoinColumnBidirectionalRefIngEntity ing2 = getEntityManager().find(DoubleListJoinColumnBidirectionalRefIngEntity.class, ing2_id);
+
+ DoubleListJoinColumnBidirectionalRefEdEntity1 rev1 = getAuditReader().find(DoubleListJoinColumnBidirectionalRefEdEntity1.class, ed1_1_id, 1);
+ DoubleListJoinColumnBidirectionalRefEdEntity1 rev2 = getAuditReader().find(DoubleListJoinColumnBidirectionalRefEdEntity1.class, ed1_1_id, 2);
+ DoubleListJoinColumnBidirectionalRefEdEntity1 rev3 = getAuditReader().find(DoubleListJoinColumnBidirectionalRefEdEntity1.class, ed1_1_id, 3);
+ DoubleListJoinColumnBidirectionalRefEdEntity1 rev4 = getAuditReader().find(DoubleListJoinColumnBidirectionalRefEdEntity1.class, ed1_1_id, 4);
+
+ assertTrue(rev1.getOwner().equals(ing1));
+ assertTrue(rev2.getOwner().equals(ing1));
+ assertTrue(rev3.getOwner().equals(ing1));
+ assertTrue(rev4.getOwner().equals(ing2));
+
+ assertEquals(rev1.getData(), "ed1_1");
+ assertEquals(rev2.getData(), "ed1_1");
+ assertEquals(rev3.getData(), "ed1_1 bis");
+ assertEquals(rev4.getData(), "ed1_1 bis");
+ }
+
+ @Test(enabled = true, dependsOnMethods = "createData")
+ public void testHistoryOfEd1_2() {
+ DoubleListJoinColumnBidirectionalRefIngEntity ing1 = getEntityManager().find(DoubleListJoinColumnBidirectionalRefIngEntity.class, ing1_id);
+ DoubleListJoinColumnBidirectionalRefIngEntity ing2 = getEntityManager().find(DoubleListJoinColumnBidirectionalRefIngEntity.class, ing2_id);
+
+ DoubleListJoinColumnBidirectionalRefEdEntity1 rev1 = getAuditReader().find(DoubleListJoinColumnBidirectionalRefEdEntity1.class, ed1_2_id, 1);
+ DoubleListJoinColumnBidirectionalRefEdEntity1 rev2 = getAuditReader().find(DoubleListJoinColumnBidirectionalRefEdEntity1.class, ed1_2_id, 2);
+ DoubleListJoinColumnBidirectionalRefEdEntity1 rev3 = getAuditReader().find(DoubleListJoinColumnBidirectionalRefEdEntity1.class, ed1_2_id, 3);
+ DoubleListJoinColumnBidirectionalRefEdEntity1 rev4 = getAuditReader().find(DoubleListJoinColumnBidirectionalRefEdEntity1.class, ed1_2_id, 4);
+
+ assertTrue(rev1.getOwner().equals(ing2));
+ assertTrue(rev2.getOwner().equals(ing1));
+ assertTrue(rev3.getOwner().equals(ing1));
+ assertTrue(rev4.getOwner().equals(ing2));
+
+ assertEquals(rev1.getData(), "ed1_2");
+ assertEquals(rev2.getData(), "ed1_2");
+ assertEquals(rev3.getData(), "ed1_2");
+ assertEquals(rev4.getData(), "ed1_2");
+ }
+
+ @Test(enabled = true, dependsOnMethods = "createData")
+ public void testHistoryOfEd2_1() {
+ DoubleListJoinColumnBidirectionalRefIngEntity ing1 = getEntityManager().find(DoubleListJoinColumnBidirectionalRefIngEntity.class, ing1_id);
+ DoubleListJoinColumnBidirectionalRefIngEntity ing2 = getEntityManager().find(DoubleListJoinColumnBidirectionalRefIngEntity.class, ing2_id);
+
+ DoubleListJoinColumnBidirectionalRefEdEntity2 rev1 = getAuditReader().find(DoubleListJoinColumnBidirectionalRefEdEntity2.class, ed2_1_id, 1);
+ DoubleListJoinColumnBidirectionalRefEdEntity2 rev2 = getAuditReader().find(DoubleListJoinColumnBidirectionalRefEdEntity2.class, ed2_1_id, 2);
+ DoubleListJoinColumnBidirectionalRefEdEntity2 rev3 = getAuditReader().find(DoubleListJoinColumnBidirectionalRefEdEntity2.class, ed2_1_id, 3);
+ DoubleListJoinColumnBidirectionalRefEdEntity2 rev4 = getAuditReader().find(DoubleListJoinColumnBidirectionalRefEdEntity2.class, ed2_1_id, 4);
+
+ assertTrue(rev1.getOwner().equals(ing1));
+ assertTrue(rev2.getOwner().equals(ing1));
+ assertTrue(rev3.getOwner().equals(ing1));
+ assertTrue(rev4.getOwner().equals(ing2));
+
+ assertEquals(rev1.getData(), "ed2_1");
+ assertEquals(rev2.getData(), "ed2_1");
+ assertEquals(rev3.getData(), "ed2_1");
+ assertEquals(rev4.getData(), "ed2_1");
+ }
+
+ @Test(enabled = true, dependsOnMethods = "createData")
+ public void testHistoryOfEd2_2() {
+ DoubleListJoinColumnBidirectionalRefIngEntity ing1 = getEntityManager().find(DoubleListJoinColumnBidirectionalRefIngEntity.class, ing1_id);
+ DoubleListJoinColumnBidirectionalRefIngEntity ing2 = getEntityManager().find(DoubleListJoinColumnBidirectionalRefIngEntity.class, ing2_id);
+
+ DoubleListJoinColumnBidirectionalRefEdEntity2 rev1 = getAuditReader().find(DoubleListJoinColumnBidirectionalRefEdEntity2.class, ed2_2_id, 1);
+ DoubleListJoinColumnBidirectionalRefEdEntity2 rev2 = getAuditReader().find(DoubleListJoinColumnBidirectionalRefEdEntity2.class, ed2_2_id, 2);
+ DoubleListJoinColumnBidirectionalRefEdEntity2 rev3 = getAuditReader().find(DoubleListJoinColumnBidirectionalRefEdEntity2.class, ed2_2_id, 3);
+ DoubleListJoinColumnBidirectionalRefEdEntity2 rev4 = getAuditReader().find(DoubleListJoinColumnBidirectionalRefEdEntity2.class, ed2_2_id, 4);
+
+ assertTrue(rev1.getOwner().equals(ing2));
+ assertTrue(rev2.getOwner().equals(ing1));
+ assertTrue(rev3.getOwner().equals(ing1));
+ assertTrue(rev4.getOwner().equals(ing1));
+
+ assertEquals(rev1.getData(), "ed2_2");
+ assertEquals(rev2.getData(), "ed2_2");
+ assertEquals(rev3.getData(), "ed2_2 bis");
+ assertEquals(rev4.getData(), "ed2_2 bis");
+ }
+}
\ No newline at end of file