From 3740a20550ef643440e47041d1ef254db25db21c Mon Sep 17 00:00:00 2001 From: Adam Warski Date: Tue, 15 Dec 2009 12:27:01 +0000 Subject: [PATCH] HHH-4694: - adding support for multiple "fake" bidirectional relations - downgrading testng back to 5.8 as using 5.10 was OOMing the tests - updating h2 dependency to a newer version git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18225 1b8cb986-b30d-0410-93ca-fae66ebed9b2 --- envers/pom.xml | 4 +- .../envers/event/AuditEventListener.java | 2 +- .../FakeBidirectionalRelationWorkUnit.java | 110 +++++-- ...stJoinColumnBidirectionalRefEdEntity1.java | 85 +++++ ...stJoinColumnBidirectionalRefEdEntity2.java | 85 +++++ ...stJoinColumnBidirectionalRefIngEntity.java | 100 ++++++ .../DoubleJoinColumnBidirectionalList.java | 299 ++++++++++++++++++ 7 files changed, 654 insertions(+), 31 deletions(-) create mode 100644 envers/src/test/java/org/hibernate/envers/test/entities/onetomany/detached/DoubleListJoinColumnBidirectionalRefEdEntity1.java create mode 100644 envers/src/test/java/org/hibernate/envers/test/entities/onetomany/detached/DoubleListJoinColumnBidirectionalRefEdEntity2.java create mode 100644 envers/src/test/java/org/hibernate/envers/test/entities/onetomany/detached/DoubleListJoinColumnBidirectionalRefIngEntity.java create mode 100644 envers/src/test/java/org/hibernate/envers/test/integration/onetomany/detached/DoubleJoinColumnBidirectionalList.java 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