From 5b8ef8154ae024ca9c433404cee4589706393ec1 Mon Sep 17 00:00:00 2001 From: Mitsch164 Date: Thu, 12 Jul 2018 05:10:17 +0200 Subject: [PATCH] Fix Transaction Flushing when ID Property is Loaded (#1450) * Fix for unintentianal flush when ID is loaded * fix duplicateKey Exception * higher id --- .../server/core/PersistRequestBean.java | 10 ++- .../server/deploy/BeanDescriptor.java | 4 + .../batchinsert/TestBatchInsertFlush.java | 74 ++++++++++++++++++- 3 files changed, 85 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/ebeaninternal/server/core/PersistRequestBean.java b/src/main/java/io/ebeaninternal/server/core/PersistRequestBean.java index 4839790ec..d3a5c9bec 100644 --- a/src/main/java/io/ebeaninternal/server/core/PersistRequestBean.java +++ b/src/main/java/io/ebeaninternal/server/core/PersistRequestBean.java @@ -356,7 +356,15 @@ public final class PersistRequestBean extends PersistRequest implements BeanP private boolean flushBatchOnGetter(int propertyIndex) { // propertyIndex of -1 the Id property, no flush for get Id on UPDATE - return propertyIndex == -1 ? type == Type.INSERT : beanDescriptor.isGeneratedProperty(propertyIndex); + if (propertyIndex == -1) { + if (beanDescriptor.isIdLoaded(intercept)) { + return false; + } else { + return type == Type.INSERT; + } + } else { + return beanDescriptor.isGeneratedProperty(propertyIndex); + } } public void setSkipBatchForTopLevel() { diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java index 1df2c0d0e..05076b078 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java @@ -3160,6 +3160,10 @@ public class BeanDescriptor implements BeanType, STreeType { public boolean hasIdPropertyOnly(EntityBeanIntercept ebi) { return ebi.hasIdOnly(idPropertyIndex); } + + public boolean isIdLoaded(EntityBeanIntercept ebi) { + return ebi.isLoadedProperty(idPropertyIndex); + } public boolean hasIdValue(EntityBean bean) { return (idProperty != null && !DmlUtil.isNullOrZero(idProperty.getValue(bean))); diff --git a/src/test/java/org/tests/batchinsert/TestBatchInsertFlush.java b/src/test/java/org/tests/batchinsert/TestBatchInsertFlush.java index 37998bfdc..8bc76c951 100644 --- a/src/test/java/org/tests/batchinsert/TestBatchInsertFlush.java +++ b/src/test/java/org/tests/batchinsert/TestBatchInsertFlush.java @@ -122,15 +122,20 @@ public class TestBatchInsertFlush extends BaseTestCase { public void transactional_flushOnGetId() { EbeanServer server = Ebean.getDefaultServer(); - + LoggedSqlCollector.start(); + EBasicVer b1 = new EBasicVer("b1"); server.save(b1); EBasicVer b2 = new EBasicVer("b2"); server.save(b2); + //flush here + assertThat(LoggedSqlCollector.current()).isEmpty(); Integer id = b1.getId(); assertNotNull(id); + assertThat(LoggedSqlCollector.current()).hasSize(2); + EBasicVer b3 = new EBasicVer("b3"); server.save(b3); } @@ -141,7 +146,8 @@ public class TestBatchInsertFlush extends BaseTestCase { EbeanServer server = Ebean.getDefaultServer(); Transaction txn = server.beginTransaction(); try { - txn.setBatch(PersistBatch.ALL); + LoggedSqlCollector.start(); + txn.setBatchMode(true); EBasicVer b1 = new EBasicVer("b1"); server.save(b1, txn); @@ -149,8 +155,11 @@ public class TestBatchInsertFlush extends BaseTestCase { EBasicVer b2 = new EBasicVer("b2"); server.save(b2, txn); + //flush here + assertThat(LoggedSqlCollector.current()).isEmpty(); Integer id = b1.getId(); assertNotNull(id); + assertThat(LoggedSqlCollector.current()).hasSize(2); EBasicVer b3 = new EBasicVer("b3"); server.save(b3, txn); @@ -161,6 +170,67 @@ public class TestBatchInsertFlush extends BaseTestCase { txn.end(); } } + + @Test + @Transactional(batch = PersistBatch.ALL) + public void transactional_noflushWhenIdIsLoaded() { + + EbeanServer server = Ebean.getDefaultServer(); + + LoggedSqlCollector.start(); + + EBasicVer b1 = new EBasicVer("b1"); + b1.setId(78965); + server.save(b1); + + EBasicVer b2 = new EBasicVer("b2"); + b2.setId(78645); + server.save(b2); + + assertThat(LoggedSqlCollector.current()).isEmpty(); + // dont flush here + Integer id = b1.getId(); + assertNotNull(id); + assertThat(LoggedSqlCollector.current()).isEmpty(); + + EBasicVer b3 = new EBasicVer("b3"); + server.save(b3); + + } + + @Test + public void noflushWhenIdIsLoaded() { + + EbeanServer server = Ebean.getDefaultServer(); + Transaction txn = server.beginTransaction(); + try { + LoggedSqlCollector.start(); + txn.setBatchMode(true); + + EBasicVer b1 = new EBasicVer("b1"); + b1.setId(546864); + server.save(b1, txn); + + EBasicVer b2 = new EBasicVer("b2"); + b2.setId(21354); + server.save(b2, txn); + + assertThat(LoggedSqlCollector.current()).isEmpty(); + //dont flush here + Integer id = b1.getId(); + assertNotNull(id); + assertThat(LoggedSqlCollector.current()).isEmpty(); + + EBasicVer b3 = new EBasicVer("b3"); + server.save(b3, txn); + + txn.commit(); + assertThat(LoggedSqlCollector.current()).hasSize(3); + + } finally { + txn.end(); + } + } @Test public void testFlushOnGetProperty() {