From a780dc133ec1f45c728712abeb4788b044f671b5 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Mon, 29 Jul 2019 22:46:39 +1200 Subject: [PATCH] #1776 Fix for - refresh does not work on oneToMany if property was not yet accessed --- .../server/deploy/BeanPropertyAssocMany.java | 7 ++- .../server/query/STreePropertyAssocMany.java | 5 ++ .../server/query/SqlTreeNodeBean.java | 52 +++++++++---------- 3 files changed, 35 insertions(+), 29 deletions(-) diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java b/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java index 3fbfb49f7..969777472 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java @@ -613,8 +613,12 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc implements ST } @Override - public BeanCollection createReferenceIfNull(EntityBean parentBean) { + public BeanCollection createReference(EntityBean localBean, boolean forceNewReference) { + return forceNewReference ? createReference(localBean) : createReferenceIfNull(localBean); + } + @Override + public BeanCollection createReferenceIfNull(EntityBean parentBean) { Object v = getValue(parentBean); if (v instanceof BeanCollection) { BeanCollection bc = (BeanCollection) v; @@ -627,7 +631,6 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc implements ST } public BeanCollection createReference(EntityBean parentBean) { - BeanCollection ref = help.createReference(parentBean); setValue(parentBean, ref); return ref; diff --git a/src/main/java/io/ebeaninternal/server/query/STreePropertyAssocMany.java b/src/main/java/io/ebeaninternal/server/query/STreePropertyAssocMany.java index 9b6791e2f..49d4fb313 100644 --- a/src/main/java/io/ebeaninternal/server/query/STreePropertyAssocMany.java +++ b/src/main/java/io/ebeaninternal/server/query/STreePropertyAssocMany.java @@ -22,6 +22,11 @@ public interface STreePropertyAssocMany extends STreePropertyAssoc { */ BeanCollection createReferenceIfNull(EntityBean localBean); + /** + * Return a reference collection forcing a new reference on REFRESH query. + */ + BeanCollection createReference(EntityBean localBean, boolean forceNewReference); + /** * Return true if the property has a join table. */ diff --git a/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeBean.java b/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeBean.java index f03d60637..fa60e1485 100644 --- a/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeBean.java +++ b/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeBean.java @@ -376,7 +376,7 @@ class SqlTreeNodeBean implements SqlTreeNode { if (!lazyLoadMany && localBean != null) { ctx.setCurrentPrefix(prefix, pathMap); if (readId && !temporalVersions) { - createListProxies(localDesc, ctx, localBean, disableLazyLoad); + createListProxies(); } if (temporalMode == SpiQuery.TemporalMode.DRAFT) { localDesc.setDraft(localBean); @@ -413,6 +413,30 @@ class SqlTreeNodeBean implements SqlTreeNode { } } + /** + * Create lazy loading proxies for the Many's except for the one that is + * included in the actual query. + */ + private void createListProxies() { + STreePropertyAssocMany fetchedMany = ctx.getManyProperty(); + boolean forceNewReference = queryMode == Mode.REFRESH_BEAN; + // load the List/Set/Map proxy objects (deferred fetching of lists) + for (STreePropertyAssocMany many : localDesc.propsMany()) { + if (many != fetchedMany) { + // create a proxy for the many (deferred fetching) + BeanCollection ref = many.createReference(localBean, forceNewReference); + if (ref != null) { + if (disableLazyLoad) { + ref.setDisableLazyLoad(true); + } + if (!ref.isRegisteredWithLoadContext()) { + ctx.register(many.getName(), ref); + } + } + } + } + } + void setBeanToParent() { if (parentBean != null) { // set this back to the parentBean @@ -463,32 +487,6 @@ class SqlTreeNodeBean implements SqlTreeNode { return load.complete(); } - /** - * Create lazy loading proxies for the Many's except for the one that is - * included in the actual query. - */ - private void createListProxies(STreeType localDesc, DbReadContext ctx, EntityBean localBean, boolean disableLazyLoad) { - - STreePropertyAssocMany fetchedMany = ctx.getManyProperty(); - - // load the List/Set/Map proxy objects (deferred fetching of lists) - for (STreePropertyAssocMany many : localDesc.propsMany()) { - - if (fetchedMany == null || !fetchedMany.equals(many)) { - // create a proxy for the many (deferred fetching) - BeanCollection ref = many.createReferenceIfNull(localBean); - if (ref != null) { - if (disableLazyLoad) { - ref.setDisableLazyLoad(true); - } - if (!ref.isRegisteredWithLoadContext()) { - ctx.register(many.getName(), ref); - } - } - } - } - } - @Override public void appendGroupBy(DbSqlContext ctx, boolean subQuery) {