diff --git a/src/main/java/com/avaje/ebeaninternal/server/persist/BatchedBeanHolder.java b/src/main/java/com/avaje/ebeaninternal/server/persist/BatchedBeanHolder.java index f997b0731..28b5e21a9 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/persist/BatchedBeanHolder.java +++ b/src/main/java/com/avaje/ebeaninternal/server/persist/BatchedBeanHolder.java @@ -2,6 +2,7 @@ package com.avaje.ebeaninternal.server.persist; import java.util.ArrayList; import java.util.HashSet; +import java.util.IdentityHashMap; import com.avaje.ebeaninternal.server.core.PersistRequest; import com.avaje.ebeaninternal.server.core.PersistRequestBean; @@ -21,6 +22,8 @@ import com.avaje.ebeaninternal.server.deploy.BeanDescriptor; */ public class BatchedBeanHolder { + private static final Object DUMMY = new Object(); + /** * The owning queue. */ @@ -48,7 +51,11 @@ public class BatchedBeanHolder { */ private ArrayList deletes; - private HashSet beanHashCodes = new HashSet(); + /** + * Set of beans in this batch. This is used to ensure that a single bean instance is not included + * in the batch twice (two separate insert requests etc). + */ + private IdentityHashMap persistedBeans = new IdentityHashMap(); /** * Create a new entry with a given type and depth. @@ -90,7 +97,7 @@ public class BatchedBeanHolder { control.executeNow(deletes); deletes.clear(); } - beanHashCodes.clear(); + persistedBeans.clear(); } public String toString() { @@ -113,8 +120,8 @@ public class BatchedBeanHolder { */ public int append(PersistRequestBean request) { - Integer objHashCode = new Integer(System.identityHashCode(request.getEntityBean())); - if (!beanHashCodes.add(objHashCode)) { + Object alreadyInBatch = persistedBeans.put(request.getEntityBean(), DUMMY); + if (alreadyInBatch != null) { // special case where the same bean instance has already been // added to the batch (doesn't really occur with non-batching // as the bean gets changed from dirty to loaded earlier) @@ -154,6 +161,6 @@ public class BatchedBeanHolder { * Return true if this is empty containing no batched beans. */ public boolean isEmpty() { - return beanHashCodes.isEmpty(); + return persistedBeans.isEmpty(); } } diff --git a/src/test/java/com/avaje/ebeaninternal/server/persist/BatchedBeanHolderTest.java b/src/test/java/com/avaje/ebeaninternal/server/persist/BatchedBeanHolderTest.java new file mode 100644 index 000000000..c727ac1e0 --- /dev/null +++ b/src/test/java/com/avaje/ebeaninternal/server/persist/BatchedBeanHolderTest.java @@ -0,0 +1,42 @@ +package com.avaje.ebeaninternal.server.persist; + +import com.avaje.ebean.Ebean; +import com.avaje.ebeaninternal.api.SpiEbeanServer; +import com.avaje.ebeaninternal.api.TDSpiEbeanServer; +import com.avaje.ebeaninternal.server.core.PersistRequest; +import com.avaje.ebeaninternal.server.core.PersistRequestBean; +import com.avaje.ebeaninternal.server.deploy.BeanDescriptor; +import com.avaje.ebeaninternal.server.deploy.BeanManager; +import com.avaje.tests.model.basic.Customer; +import org.junit.Test; +import org.mockito.Mockito; + +import static org.junit.Assert.assertEquals; + +public class BatchedBeanHolderTest { + + @Test + public void testAppend() throws Exception { + + + TDSpiEbeanServer server = new TDSpiEbeanServer("foo"); + + BeanDescriptor beanDescriptor = Mockito.mock(BeanDescriptor.class); + BeanManager beanManager = new BeanManager(beanDescriptor, null); + + + BatchedBeanHolder holder = new BatchedBeanHolder(null, beanDescriptor, 1); + + Customer customer = new Customer(); + PersistRequestBean req1 = new PersistRequestBean(server, customer, null, beanManager, null, null, PersistRequest.Type.INSERT, false); + + + int size = holder.append(req1); + assertEquals(1, size); + + PersistRequestBean req2 = new PersistRequestBean(server, customer, null, beanManager, null, null, PersistRequest.Type.INSERT, false); + size = holder.append(req2); + assertEquals(0, size); + + } +} \ No newline at end of file