diff --git a/README.md b/README.md
index 732345e169..785b48c0e9 100644
--- a/README.md
+++ b/README.md
@@ -59,11 +59,6 @@ Work at the highest level of abstraction and drop down levels as needed.
-
-
-
-
- |
diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/ScopeTrans.java b/ebean-core/src/main/java/io/ebeaninternal/api/ScopeTrans.java
index 348f1e4a48..00f54d9877 100644
--- a/ebean-core/src/main/java/io/ebeaninternal/api/ScopeTrans.java
+++ b/ebean-core/src/main/java/io/ebeaninternal/api/ScopeTrans.java
@@ -142,6 +142,8 @@ void commitTransaction() {
transaction.commit();
} else {
nestedCommit = true;
+ transaction.flush();
+ // restore the batch settings
transaction.setFlushOnQuery(restoreBatchFlushOnQuery);
transaction.setBatchMode(restoreBatch);
transaction.setBatchOnCascade(restoreBatchOnCascade);
diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/ScopedTransaction.java b/ebean-core/src/main/java/io/ebeaninternal/api/ScopedTransaction.java
index 9f46c97a7f..c5762c0d0f 100644
--- a/ebean-core/src/main/java/io/ebeaninternal/api/ScopedTransaction.java
+++ b/ebean-core/src/main/java/io/ebeaninternal/api/ScopedTransaction.java
@@ -168,7 +168,7 @@ public Error caughtError(Error e) {
/**
* Maybe rollback based on TxScope rollback on settings.
*/
- public Exception caughtThrowable(Exception e) {
+ public T caughtThrowable(T e) {
return current.caughtThrowable(e);
}
diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java
index 3303027877..d3a376e706 100644
--- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java
+++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java
@@ -680,6 +680,8 @@ public T executeCall(@Nullable TxScope scope, Callable callable) {
return callable.call();
} catch (Error e) {
throw scopeTrans.caughtError(e);
+ } catch (PersistenceException e) {
+ throw scopeTrans.caughtThrowable(e);
} catch (Exception e) {
throw new PersistenceException(scopeTrans.caughtThrowable(e));
} finally {
@@ -699,6 +701,8 @@ public void execute(@Nullable TxScope scope, Runnable runnable) {
runnable.run();
} catch (Error e) {
throw t.caughtError(e);
+ } catch (PersistenceException e) {
+ throw t.caughtThrowable(e);
} catch (Exception e) {
throw new PersistenceException(t.caughtThrowable(e));
} finally {
diff --git a/ebean-test/src/test/java/org/tests/transaction/TestExecuteComplete.java b/ebean-test/src/test/java/org/tests/transaction/TestExecuteComplete.java
index db31d630fd..2975257322 100644
--- a/ebean-test/src/test/java/org/tests/transaction/TestExecuteComplete.java
+++ b/ebean-test/src/test/java/org/tests/transaction/TestExecuteComplete.java
@@ -67,7 +67,7 @@ public void nestedExecute_when_errorOnCommit_threadLocalIsCleared() {
@ForPlatform(Platform.H2)
@Test
- public void transactional_errorOnCommit_expect_threadScopeCleanup() {
+ void transactional_errorOnCommit_expect_threadScopeCleanup() {
try {
errorOnCommit();
fail();
diff --git a/ebean-test/src/test/java/org/tests/transaction/TestNested.java b/ebean-test/src/test/java/org/tests/transaction/TestNested.java
index 7987698317..3389f27cb0 100644
--- a/ebean-test/src/test/java/org/tests/transaction/TestNested.java
+++ b/ebean-test/src/test/java/org/tests/transaction/TestNested.java
@@ -9,11 +9,10 @@
import static org.assertj.core.api.Assertions.assertThat;
-public class TestNested extends BaseTestCase {
+class TestNested extends BaseTestCase {
@Test
- public void testRunnableFail() {
-
+ void testRunnableFail() {
try {
DB.execute(this::willFail);
} catch (PersistenceException e) {
@@ -22,8 +21,7 @@ public void testRunnableFail() {
}
@Test
- public void testCallableFail() {
-
+ void testCallableFail() {
try {
DB.execute(this::willFailCallable);
} catch (PersistenceException e) {
diff --git a/ebean-test/src/test/java/org/tests/transaction/TestNestedTransaction.java b/ebean-test/src/test/java/org/tests/transaction/TestNestedTransaction.java
index 4e4887ac38..737ebf889a 100644
--- a/ebean-test/src/test/java/org/tests/transaction/TestNestedTransaction.java
+++ b/ebean-test/src/test/java/org/tests/transaction/TestNestedTransaction.java
@@ -1,14 +1,17 @@
package org.tests.transaction;
-import io.ebean.TxScope;
-import io.ebean.xtest.BaseTestCase;
import io.ebean.DB;
import io.ebean.Transaction;
+import io.ebean.TxScope;
+import io.ebean.test.LoggedSql;
+import io.ebean.xtest.BaseTestCase;
+import org.assertj.core.api.ListAssert;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tests.model.basic.EBasic;
+import org.tests.model.basic.EBasicVer;
import static org.assertj.core.api.Assertions.assertThat;
@@ -251,4 +254,43 @@ public void test_txn_with_BatchMode() {
}
}
+ @Test
+ public void test_txn_nestedWithInnerBatch() {
+ try (Transaction txn1 = DB.beginTransaction()) {
+ txn1.setFlushOnQuery(false);
+ try (Transaction txn2 = DB.beginTransaction()) {
+ LoggedSql.start();
+ txn2.setBatchMode(true);
+
+ EBasicVer basic = new EBasicVer("New name");
+ basic.setId(1000);
+ basic.setDescription("New description");
+ DB.save(basic);
+
+ txn2.flush();
+
+ basic.setName("OtherName");
+ DB.save(basic);
+
+ // should perform a flush
+ txn2.commit();
+
+ ListAssert sqlAssert = assertThat(LoggedSql.stop()).hasSize(6);
+ sqlAssert.element(0).asString().contains("insert into e_basicver");
+ sqlAssert.element(1).asString().contains("-- bind(1000,New name");
+ sqlAssert.element(2).asString().contains("-- executeBatch() size:1");
+ sqlAssert.element(3).asString().contains("update e_basicver");
+ sqlAssert.element(4).asString().contains("-- bind(OtherName,");
+ sqlAssert.element(5).asString().contains("-- executeBatch() size:1");
+ }
+
+ // we expect the changes in the nested transaction to made visible
+ // regardless of the other transactions flushOnQuery mode
+ EBasicVer eBasicVer = DB.find(EBasicVer.class, 1000);
+ assertThat(eBasicVer.getName())
+ .describedAs("changes in nested transaction were not flushed")
+ .isEqualTo("OtherName");
+ }
+ }
+
}
|