Merge branch 'circular_saves_bugs' of https://github.com/tobias-/ebean into tobias--circular_saves_bugs

This commit is contained in:
rob bygrave
2019-06-10 21:03:55 +12:00
5 changed files with 283 additions and 0 deletions
@@ -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());
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}