From 721654d0335afe71b9c9c6eeda305557ef4b0ba8 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 3 Oct 2017 12:47:29 +1300 Subject: [PATCH] #1140 - Error loading embedded instance The issue was due to the loaded status not being recursively set on embedded beans after inserts. The test case invoked lazy loading due to that which lead to the issue. --- .../io/ebean/bean/EntityBeanIntercept.java | 9 +++++++ .../server/core/PersistRequestBean.java | 6 +---- .../server/deploy/BeanDescriptor.java | 9 +++---- .../server/deploy/BeanPropertyAssocOne.java | 9 +++---- .../org/tests/embedded/TestEmbeddedEmpty.java | 24 +++++++++++++++++++ 5 files changed, 44 insertions(+), 13 deletions(-) create mode 100644 src/test/java/org/tests/embedded/TestEmbeddedEmpty.java diff --git a/src/main/java/io/ebean/bean/EntityBeanIntercept.java b/src/main/java/io/ebean/bean/EntityBeanIntercept.java index d1dc7a77b..1789519a9 100644 --- a/src/main/java/io/ebean/bean/EntityBeanIntercept.java +++ b/src/main/java/io/ebean/bean/EntityBeanIntercept.java @@ -507,6 +507,15 @@ public final class EntityBeanIntercept implements Serializable { loadedProps[propertyIndex] = true; } + /** + * Set all properties to be loaded (post insert). + */ + public void setLoadedPropertyAll() { + for (int i = 0; i < loadedProps.length; i++) { + loadedProps[i] = true; + } + } + /** * Return true if the property is loaded. */ diff --git a/src/main/java/io/ebeaninternal/server/core/PersistRequestBean.java b/src/main/java/io/ebeaninternal/server/core/PersistRequestBean.java index e7270f01e..e9ee824cf 100644 --- a/src/main/java/io/ebeaninternal/server/core/PersistRequestBean.java +++ b/src/main/java/io/ebeaninternal/server/core/PersistRequestBean.java @@ -938,11 +938,7 @@ public final class PersistRequestBean extends PersistRequest implements BeanP private void postInsert() { // mark all properties as loaded after an insert to support immediate update - int len = intercept.getPropertyLength(); - for (int i = 0; i < len; i++) { - intercept.setLoadedProperty(i); - } - beanDescriptor.setEmbeddedOwner(entityBean); + beanDescriptor.setAllLoaded(entityBean); if (!publish) { beanDescriptor.setDraft(entityBean); } diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java index 4972cff0f..1e0ec0bb2 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java @@ -2793,11 +2793,12 @@ public class BeanDescriptor implements MetaBeanInfo, BeanType { } /** - * Set the embedded owner on any embedded bean properties. + * Set all properties to be loaded (recurse to embedded beans). */ - public void setEmbeddedOwner(EntityBean bean) { - for (BeanPropertyAssocOne aPropertiesEmbedded : propertiesEmbedded) { - aPropertiesEmbedded.setEmbeddedOwner(bean); + public void setAllLoaded(EntityBean bean) { + bean._ebean_getIntercept().setLoadedPropertyAll(); + for (BeanPropertyAssocOne embedded : propertiesEmbedded) { + embedded.setAllLoadedEmbedded(bean); } } diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocOne.java b/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocOne.java index 21451dfb4..34e9b248d 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocOne.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocOne.java @@ -609,13 +609,14 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc { } /** - * Set the owner on the embedded bean property. + * For embedded bean set the owner and all properties to be loaded (recursively). */ - void setEmbeddedOwner(EntityBean owner) { - + void setAllLoadedEmbedded(EntityBean owner) { Object emb = getValue(owner); if (emb != null) { - setEmbeddedOwner(owner, emb); + EntityBean embeddedBean = (EntityBean) emb; + embeddedBean._ebean_getIntercept().setEmbeddedOwner(owner, propertyIndex); + targetDescriptor.setAllLoaded(embeddedBean); } } diff --git a/src/test/java/org/tests/embedded/TestEmbeddedEmpty.java b/src/test/java/org/tests/embedded/TestEmbeddedEmpty.java new file mode 100644 index 000000000..a8c503d9a --- /dev/null +++ b/src/test/java/org/tests/embedded/TestEmbeddedEmpty.java @@ -0,0 +1,24 @@ +package org.tests.embedded; + +import io.ebean.Ebean; +import org.junit.Test; +import org.tests.model.embedded.EAddress; +import org.tests.model.embedded.EPerson; + +public class TestEmbeddedEmpty { + + @Test + public void insertEmptyEmbedded() { + + EPerson person = new EPerson(); + person.setName("with empty embedded"); + + // set empty embedded bean + person.setAddress(new EAddress()); + + Ebean.save(person); + + // treat all embedded properties as loaded + person.getAddress().getCity(); + } +}