Testcase for ebean with circular dependences

1. While the javax.persistance api discourages the use of bidirectional
   cascades, it does not prohibit them. They're very useful and natural
   if you think of the database as a graph instead of a tree.
   test case 1 (testCircularCascade) tests this.
2. Second test case fetches the child, but saves the parent. If used like
   that, the child will not have it's changes saved.
This commit is contained in:
Snōwball
2019-05-23 16:38:55 +02:00
parent aececa2199
commit 3bf9dd6743
5 changed files with 266 additions and 0 deletions
@@ -0,0 +1,75 @@
package org.tests.update;
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 testFetchChildSaveParent() {
long dId = createCAndD();
modifyPropertyToTrue2(dId);
Parent parent = Ebean.find(Parent.class, dId);
assert parent != null;
// Fails here because D was not saved even though C has cascade = ALL
assertTrue(parent.getChild().isTestProperty());
}
private void modifyPropertyToTrue2(long dId) {
Child child = Ebean.find(Child.class, dId);
assert child != null;
child.setTestProperty(true);
final Parent parent = child.getParent();
Ebean.save(parent);
}
private long createCAndD() {
Parent parent = new Parent();
Child child = new Child();
parent.setChild(child);
Ebean.save(parent);
return 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(mappedBy = "child")
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)
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;
}
}