diff --git a/src/main/java/com/avaje/ebean/bean/BeanCollection.java b/src/main/java/com/avaje/ebean/bean/BeanCollection.java index 2ddbf242f..f9b2737d7 100644 --- a/src/main/java/com/avaje/ebean/bean/BeanCollection.java +++ b/src/main/java/com/avaje/ebean/bean/BeanCollection.java @@ -125,6 +125,11 @@ public interface BeanCollection extends Serializable { */ void internalAdd(Object bean); + /** + * Add the bean with a check to see if it is already contained. + */ + void internalAddWithCheck(Object bean); + /** * Return the number of elements in the List Set or Map. */ diff --git a/src/main/java/com/avaje/ebean/common/BeanList.java b/src/main/java/com/avaje/ebean/common/BeanList.java index f358c79f5..1ce9aa2d3 100644 --- a/src/main/java/com/avaje/ebean/common/BeanList.java +++ b/src/main/java/com/avaje/ebean/common/BeanList.java @@ -1,5 +1,9 @@ package com.avaje.ebean.common; +import com.avaje.ebean.bean.BeanCollectionAdd; +import com.avaje.ebean.bean.BeanCollectionLoader; +import com.avaje.ebean.bean.EntityBean; + import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; @@ -8,17 +12,13 @@ import java.util.Iterator; import java.util.List; import java.util.ListIterator; -import com.avaje.ebean.bean.BeanCollectionAdd; -import com.avaje.ebean.bean.BeanCollectionLoader; -import com.avaje.ebean.bean.EntityBean; - /** * List capable of lazy loading. */ public final class BeanList extends AbstractBeanCollection implements List, BeanCollectionAdd { private static final long serialVersionUID = 1L; - + /** * The underlying List implementation. */ @@ -74,6 +74,13 @@ public final class BeanList extends AbstractBeanCollection implements List } } + @Override + public void internalAddWithCheck(Object bean) { + if (list == null || !list.contains(bean)) { + internalAdd(bean); + } + } + public boolean checkEmptyLazyLoad() { if (list == null) { list = new ArrayList(); @@ -99,11 +106,11 @@ public final class BeanList extends AbstractBeanCollection implements List private void initAsUntouched() { init(false); } - + private void init() { init(true); } - + private void init(boolean setTouched) { synchronized (this) { if (list == null) { @@ -134,7 +141,7 @@ public final class BeanList extends AbstractBeanCollection implements List public Collection getActualDetails() { return list; } - + @Override public Collection getActualEntries() { return list; diff --git a/src/main/java/com/avaje/ebean/common/BeanMap.java b/src/main/java/com/avaje/ebean/common/BeanMap.java index 0f2419474..60190e386 100644 --- a/src/main/java/com/avaje/ebean/common/BeanMap.java +++ b/src/main/java/com/avaje/ebean/common/BeanMap.java @@ -66,7 +66,18 @@ public final class BeanMap extends AbstractBeanCollection implements Ma map.put((K) key, (E) bean); } } - + + public void internalPutWithCheck(Object key, Object bean) { + if (map == null || !map.containsKey(key)) { + internalPut(key, bean); + } + } + + @Override + public void internalAddWithCheck(Object bean) { + throw new RuntimeException("Not allowed for map"); + } + public void internalAdd(Object bean) { throw new RuntimeException("Not allowed for map"); } diff --git a/src/main/java/com/avaje/ebean/common/BeanSet.java b/src/main/java/com/avaje/ebean/common/BeanSet.java index 23d030372..feda082d0 100644 --- a/src/main/java/com/avaje/ebean/common/BeanSet.java +++ b/src/main/java/com/avaje/ebean/common/BeanSet.java @@ -1,15 +1,15 @@ package com.avaje.ebean.common; +import com.avaje.ebean.bean.BeanCollectionAdd; +import com.avaje.ebean.bean.BeanCollectionLoader; +import com.avaje.ebean.bean.EntityBean; + import java.io.Serializable; import java.util.Collection; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Set; -import com.avaje.ebean.bean.BeanCollectionAdd; -import com.avaje.ebean.bean.BeanCollectionLoader; -import com.avaje.ebean.bean.EntityBean; - /** * Set capable of lazy loading. */ @@ -57,6 +57,13 @@ public final class BeanSet extends AbstractBeanCollection implements Set extends AbstractBeanCollection implements Set { /** * Add a bean to the List Set or Map. */ - void add(BeanCollection collection, EntityBean bean); + void add(BeanCollection collection, EntityBean bean, boolean withCheck); /** * Create a lazy loading proxy for a List Set or Map. diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanListHelp.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanListHelp.java index 8f4dd78d3..c44ee4e56 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanListHelp.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanListHelp.java @@ -46,8 +46,12 @@ public final class BeanListHelp implements BeanCollectionHelp { * Internal add bypassing any modify listening. */ @Override - public void add(BeanCollection collection, EntityBean bean) { - collection.internalAdd(bean); + public void add(BeanCollection collection, EntityBean bean, boolean withCheck) { + if (withCheck) { + collection.internalAddWithCheck(bean); + } else { + collection.internalAdd(bean); + } } @Override diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanMapHelp.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanMapHelp.java index cfc413e83..363a293ef 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanMapHelp.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanMapHelp.java @@ -108,13 +108,14 @@ public final class BeanMapHelp implements BeanCollectionHelp { } @Override - public void add(BeanCollection collection, EntityBean bean) { + public void add(BeanCollection collection, EntityBean bean, boolean withCheck) { if (bean == null) { ((BeanMap) collection).internalPutNull(); } else { Object keyValue = beanProperty.getValueIntercept(bean); - ((BeanMap) collection).internalPut(keyValue, bean); + BeanMap map = ((BeanMap) collection); + map.internalPutWithCheck(keyValue, bean); } } diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocMany.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocMany.java index b08e86679..8cf145d66 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocMany.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocMany.java @@ -182,13 +182,13 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc { /** * Add the bean to the appropriate collection on the parent bean. */ - public void addBeanToCollectionWithCreate(EntityBean parentBean, EntityBean detailBean) { + public void addBeanToCollectionWithCreate(EntityBean parentBean, EntityBean detailBean, boolean withCheck) { BeanCollection bc = (BeanCollection) super.getValue(parentBean); if (bc == null) { bc = help.createEmpty(parentBean); setValue(parentBean, bc); } - help.add(bc, detailBean); + help.add(bc, detailBean, withCheck); } /** @@ -416,7 +416,7 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc { } public void add(BeanCollection collection, EntityBean bean) { - help.add(collection, bean); + help.add(collection, bean, false); } /** diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanSetHelp.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanSetHelp.java index 38ca39ea2..b1f88c4db 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanSetHelp.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanSetHelp.java @@ -61,8 +61,12 @@ public final class BeanSetHelp implements BeanCollectionHelp { } } - public void add(BeanCollection collection, EntityBean bean) { - collection.internalAdd(bean); + public void add(BeanCollection collection, EntityBean bean, boolean withCheck) { + if (withCheck) { + collection.internalAddWithCheck(bean); + } else { + collection.internalAdd(bean); + } } @Override diff --git a/src/main/java/com/avaje/ebeaninternal/server/query/CQuery.java b/src/main/java/com/avaje/ebeaninternal/server/query/CQuery.java index acfad406b..346d83ab8 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/query/CQuery.java +++ b/src/main/java/com/avaje/ebeaninternal/server/query/CQuery.java @@ -399,7 +399,7 @@ public class CQuery implements DbReadContext, CancelableQuery { } // add the loadedBean to the appropriate collection of lazyLoadParentBean - lazyLoadManyProperty.addBeanToCollectionWithCreate(lazyLoadParentBean, bean); + lazyLoadManyProperty.addBeanToCollectionWithCreate(lazyLoadParentBean, bean, true); } } @@ -542,7 +542,7 @@ public class CQuery implements DbReadContext, CancelableQuery { while (hasNext()) { EntityBean bean = next(); - help.add(collection, bean); + help.add(collection, bean, false); } updateExecutionStatistics(); diff --git a/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeBean.java b/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeBean.java index 436388776..c48697455 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeBean.java +++ b/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeBean.java @@ -347,7 +347,7 @@ public class SqlTreeNodeBean implements SqlTreeNode { return localBean; } else { - if (lazyLoadParentId != null && newBean) { + if (lazyLoadParentId != null) { ctx.setLazyLoadedChildBean(contextBean, lazyLoadParentId); } return contextBean; diff --git a/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeManyRoot.java b/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeManyRoot.java index 2990ca936..024b2c317 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeManyRoot.java +++ b/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeManyRoot.java @@ -24,7 +24,7 @@ public final class SqlTreeNodeManyRoot extends SqlTreeNodeBean { // being set to the parentBean directly EntityBean detailBean = super.load(cquery, null, null); // initialise the collection and add detailBean if it is not null - manyProp.addBeanToCollectionWithCreate(contextParent, detailBean); + manyProp.addBeanToCollectionWithCreate(contextParent, detailBean, false); return detailBean; }