diff --git a/src/test/java/org/tests/update/TestUpdateCircularSave.java b/src/test/java/org/tests/update/TestUpdateCircularSave.java new file mode 100644 index 000000000..6d82e5fe0 --- /dev/null +++ b/src/test/java/org/tests/update/TestUpdateCircularSave.java @@ -0,0 +1,92 @@ +package org.tests.update; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import io.ebean.BaseTestCase; +import io.ebean.Ebean; +import org.junit.Test; +import org.tests.update.objects.SiblingA; +import org.tests.update.objects.Parent; +import org.tests.update.objects.SiblingB; +import org.tests.update.objects.Child; + +public class TestUpdateCircularSave extends BaseTestCase { + + @Test + public void testCircularCascade() { + + long aId = createA(); + modifyPropertyToTrue(aId); + + SiblingA siblingA = Ebean.find(SiblingA.class, aId); + assert siblingA != null; + assertTrue(siblingA.getSiblingB().isTestProperty()); + } + + private void modifyPropertyToTrue(long aId) { + SiblingA siblingA = Ebean.find(SiblingA.class, aId); + assert siblingA != null; + + final SiblingB siblingB = siblingA.getSiblingB(); + siblingB.setTestProperty(true); + // Will get optimistic lock as version is increased twice on B + Ebean.save(siblingB); + } + + private long createA() { + SiblingA siblingA = new SiblingA(); + SiblingB siblingB = new SiblingB(); + siblingA.setSiblingB(siblingB); + + Ebean.save(siblingA); + return siblingA.getId(); + } + + + @Test + public void testFetchChildModifyChildSaveParent() { + + long childId = createParentAndChild().getChild().getId(); + + Child child = Ebean.find(Child.class, childId); + assert child != null; + + child.setTestProperty(true); + final Parent parent = child.getParent(); + Ebean.save(parent); + + assertChildModified(childId); + } + + private void assertChildModified(long childId) { + Parent parent = Ebean.find(Parent.class, childId); + assert parent != null; + // Fails here because D was not saved even though C has cascade = ALL + assertTrue(parent.getChild().isTestProperty()); + assertEquals(parent.getChild().getVersion(), 2L); + } + + private Parent createParentAndChild() { + Parent parent = new Parent(); + Child child = new Child(); + parent.setChild(child); + + Ebean.save(parent); + return parent; + } + + + @Test + public void testFetchParentModifyChildSaveParent() { + long parentId = createParentAndChild().getId(); + + Parent parent = Ebean.find(Parent.class, parentId); + assert parent != null; + + parent.getChild().setTestProperty(true); + Ebean.save(parent); + + assertChildModified(parent.getChild().getId()); + } +} diff --git a/src/test/java/org/tests/update/objects/Child.java b/src/test/java/org/tests/update/objects/Child.java new file mode 100644 index 000000000..b8a91a2b7 --- /dev/null +++ b/src/test/java/org/tests/update/objects/Child.java @@ -0,0 +1,52 @@ +package org.tests.update.objects; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import javax.persistence.Version; + +@Entity +@Table(name = "e_save_test_d") +public class Child { + @Id + private Long id; + @Version + private long version = 0L; + @OneToOne + private Parent parent; + + private boolean testProperty = false; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public long getVersion() { + return version; + } + + public void setVersion(long version) { + this.version = version; + } + + public Parent getParent() { + return parent; + } + + public void setParent(Parent parent) { + this.parent = parent; + } + + public boolean isTestProperty() { + return testProperty; + } + + public void setTestProperty(boolean testProperty) { + this.testProperty = testProperty; + } +} diff --git a/src/test/java/org/tests/update/objects/Parent.java b/src/test/java/org/tests/update/objects/Parent.java new file mode 100644 index 000000000..bdcfa58f9 --- /dev/null +++ b/src/test/java/org/tests/update/objects/Parent.java @@ -0,0 +1,43 @@ +package org.tests.update.objects; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import javax.persistence.Version; + +@Entity +@Table(name = "e_save_test_c") +public class Parent { + @Id + private Long id; + @Version + private long version = 0L; + @OneToOne(cascade = CascadeType.ALL, mappedBy = "parent") + private Child child; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public long getVersion() { + return version; + } + + public void setVersion(long version) { + this.version = version; + } + + public Child getChild() { + return child; + } + + public void setChild(Child child) { + this.child = child; + } +} diff --git a/src/test/java/org/tests/update/objects/SiblingA.java b/src/test/java/org/tests/update/objects/SiblingA.java new file mode 100644 index 000000000..2e5806657 --- /dev/null +++ b/src/test/java/org/tests/update/objects/SiblingA.java @@ -0,0 +1,43 @@ +package org.tests.update.objects; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import javax.persistence.Version; + +@Entity +@Table(name = "e_save_test_a") +public class SiblingA { + @Id + private Long id; + @Version + private long version = 0L; + @OneToOne(cascade = CascadeType.ALL, mappedBy = "siblingA") + private SiblingB siblingB; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public long getVersion() { + return version; + } + + public void setVersion(long version) { + this.version = version; + } + + public SiblingB getSiblingB() { + return siblingB; + } + + public void setSiblingB(SiblingB siblingB) { + this.siblingB = siblingB; + } +} diff --git a/src/test/java/org/tests/update/objects/SiblingB.java b/src/test/java/org/tests/update/objects/SiblingB.java new file mode 100644 index 000000000..63b358645 --- /dev/null +++ b/src/test/java/org/tests/update/objects/SiblingB.java @@ -0,0 +1,53 @@ +package org.tests.update.objects; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import javax.persistence.Version; + +@Entity +@Table(name = "e_save_test_b") +public class SiblingB { + @Id + private Long id; + @Version + private long version = 0L; + @OneToOne(cascade = CascadeType.ALL) + private SiblingA siblingA; + + private boolean testProperty = false; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public long getVersion() { + return version; + } + + public void setVersion(long version) { + this.version = version; + } + + public SiblingA getSiblingA() { + return siblingA; + } + + public void setSiblingA(SiblingA siblingA) { + this.siblingA = siblingA; + } + + public boolean isTestProperty() { + return testProperty; + } + + public void setTestProperty(boolean testProperty) { + this.testProperty = testProperty; + } +}