From 5ff71324d0a15996d09a33fef44ee1dafbf02432 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 2 Feb 2018 20:43:55 +1300 Subject: [PATCH] #1247 - Unique index or primary key violation - when jdbc batch cascading to PrivateOwned child with unique constraint --- .../server/persist/BatchedBeanHolder.java | 8 +++--- .../cascade/TestPrivateOwnedCascadeOrder.java | 27 +++++++++++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/ebeaninternal/server/persist/BatchedBeanHolder.java b/src/main/java/io/ebeaninternal/server/persist/BatchedBeanHolder.java index e93e1e492..cfe05cd8c 100644 --- a/src/main/java/io/ebeaninternal/server/persist/BatchedBeanHolder.java +++ b/src/main/java/io/ebeaninternal/server/persist/BatchedBeanHolder.java @@ -84,6 +84,10 @@ public class BatchedBeanHolder { // with binding addBatch() for each request. // Note updates and deletes can result in many PreparedStatements // if their where clauses differ via use of IS NOT NULL. + if (deletes != null && !deletes.isEmpty()) { + control.executeNow(deletes); + deletes.clear(); + } if (inserts != null && !inserts.isEmpty()) { control.executeNow(inserts); inserts.clear(); @@ -92,10 +96,6 @@ public class BatchedBeanHolder { control.executeNow(updates); updates.clear(); } - if (deletes != null && !deletes.isEmpty()) { - control.executeNow(deletes); - deletes.clear(); - } persistedBeans.clear(); } diff --git a/src/test/java/org/tests/cascade/TestPrivateOwnedCascadeOrder.java b/src/test/java/org/tests/cascade/TestPrivateOwnedCascadeOrder.java index 10cdbdafb..2f66a8a3a 100644 --- a/src/test/java/org/tests/cascade/TestPrivateOwnedCascadeOrder.java +++ b/src/test/java/org/tests/cascade/TestPrivateOwnedCascadeOrder.java @@ -2,6 +2,7 @@ package org.tests.cascade; import io.ebean.BaseTestCase; import io.ebean.Ebean; +import io.ebean.Transaction; import org.junit.Test; import org.tests.model.basic.TSDetail; import org.tests.model.basic.TSMaster; @@ -27,4 +28,30 @@ public class TestPrivateOwnedCascadeOrder extends BaseTestCase { Ebean.save(master1); } + + @Test + public void testWithTransaction() { + + // setup + TSMaster master = new TSMaster(); + master.getDetails().add(new TSDetail("d97", "ONE2")); + master.getDetails().add(new TSDetail("d96", "TWO2")); + + Ebean.save(master); + + // act + TSMaster master1 = Ebean.find(master.getClass(), master.getId()); + + // Check Ebean deletes the existing c97 first as the unique values clash + Transaction transaction = Ebean.beginTransaction(); + try { + master1.getDetails().clear(); + master1.getDetails().add(new TSDetail("d98", "TWO2")); + + Ebean.save(master1); + transaction.commit(); + } finally { + transaction.end(); + } + } }