From 563293f7a9fb595bb5adb13223ff0bae84428dc8 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 30 Apr 2014 00:01:54 +1200 Subject: [PATCH] Test case and fix for #113 (395) : On save @OneToOne does not cascade parent IDs to child node --- .../server/deploy/BeanPropertyAssocOne.java | 14 ++++++ .../server/persist/DefaultPersister.java | 1 + .../avaje/tests/model/onetoone/OtoChild.java | 42 ++++++++++++++++++ .../avaje/tests/model/onetoone/OtoMaster.java | 43 +++++++++++++++++++ .../onetoone/TestOneToOneCascadeSave.java | 36 ++++++++++++++++ 5 files changed, 136 insertions(+) create mode 100644 src/test/java/com/avaje/tests/model/onetoone/OtoChild.java create mode 100644 src/test/java/com/avaje/tests/model/onetoone/OtoMaster.java create mode 100644 src/test/java/com/avaje/tests/model/onetoone/TestOneToOneCascadeSave.java diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocOne.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocOne.java index 3596113fb..7c6f3695b 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocOne.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocOne.java @@ -862,4 +862,18 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc { EntityBean eb = (EntityBean)detailBean; return targetDescriptor.isReference(eb._ebean_getIntercept()); } + + /** + * Set the parent bean to the child bean if it has not already been set. + */ + public void setParentBeanToChild(EntityBean parent, EntityBean child) { + + if (mappedBy != null) { + BeanProperty beanProperty = targetDescriptor.getBeanProperty(mappedBy); + if (beanProperty != null && beanProperty.getValue(child) == null) { + // set the 'parent' bean to the 'child' bean + beanProperty.setValue(child, parent); + } + } + } } diff --git a/src/main/java/com/avaje/ebeaninternal/server/persist/DefaultPersister.java b/src/main/java/com/avaje/ebeaninternal/server/persist/DefaultPersister.java index 86d8b6981..b8ac8f42c 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/persist/DefaultPersister.java +++ b/src/main/java/com/avaje/ebeaninternal/server/persist/DefaultPersister.java @@ -558,6 +558,7 @@ public final class DefaultPersister implements Persister { // skip saving this bean } else { t.depth(+1); + prop.setParentBeanToChild(parentBean, detailBean); saveRecurse(detailBean, t, parentBean); t.depth(-1); } diff --git a/src/test/java/com/avaje/tests/model/onetoone/OtoChild.java b/src/test/java/com/avaje/tests/model/onetoone/OtoChild.java new file mode 100644 index 000000000..458fa95c3 --- /dev/null +++ b/src/test/java/com/avaje/tests/model/onetoone/OtoChild.java @@ -0,0 +1,42 @@ +package com.avaje.tests.model.onetoone; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToOne; + +@Entity +public class OtoChild { + + @Id + Integer id; + + String name; + + @OneToOne + OtoMaster master; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public OtoMaster getMaster() { + return master; + } + + public void setMaster(OtoMaster master) { + this.master = master; + } + +} \ No newline at end of file diff --git a/src/test/java/com/avaje/tests/model/onetoone/OtoMaster.java b/src/test/java/com/avaje/tests/model/onetoone/OtoMaster.java new file mode 100644 index 000000000..683600b84 --- /dev/null +++ b/src/test/java/com/avaje/tests/model/onetoone/OtoMaster.java @@ -0,0 +1,43 @@ +package com.avaje.tests.model.onetoone; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToOne; + +@Entity +public class OtoMaster { + + @Id + Long id; + + String name; + + @OneToOne(cascade = CascadeType.ALL, mappedBy = "master") + OtoChild child; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public OtoChild getChild() { + return child; + } + + public void setChild(OtoChild child) { + this.child = child; + } + +} diff --git a/src/test/java/com/avaje/tests/model/onetoone/TestOneToOneCascadeSave.java b/src/test/java/com/avaje/tests/model/onetoone/TestOneToOneCascadeSave.java new file mode 100644 index 000000000..f5ad02677 --- /dev/null +++ b/src/test/java/com/avaje/tests/model/onetoone/TestOneToOneCascadeSave.java @@ -0,0 +1,36 @@ +package com.avaje.tests.model.onetoone; + +import org.junit.Assert; +import org.junit.Test; + +import com.avaje.ebean.BaseTestCase; +import com.avaje.ebean.Ebean; + +public class TestOneToOneCascadeSave extends BaseTestCase { + + @Test + public void test() { + + + OtoMaster master = new OtoMaster(); + master.setName("CName"); + + OtoChild child = new OtoChild(); + child.setName("OName"); + + master.setChild(child); + // The parent customer object should be automatically set onto the child + // object if it is currently null so you don't need to do the extra + // o.setCustomer(c); + + Ebean.save(master); + + Assert.assertNotNull(child.getId()); + + OtoChild child2 = Ebean.find(OtoChild.class, child.getId()); + OtoMaster master2 = child2.getMaster(); + Assert.assertNotNull(master2); + + } + +}