diff --git a/jOOQ-examples/jOOQ-spring-example/.classpath b/jOOQ-examples/jOOQ-spring-example/.classpath
index 0516d475c7..b68034cc95 100644
--- a/jOOQ-examples/jOOQ-spring-example/.classpath
+++ b/jOOQ-examples/jOOQ-spring-example/.classpath
@@ -19,7 +19,7 @@
-
+
diff --git a/jOOQ-examples/jOOQ-spring-example/.settings/org.eclipse.jdt.core.prefs b/jOOQ-examples/jOOQ-spring-example/.settings/org.eclipse.jdt.core.prefs
index e6f968da5e..0b7d1d1a31 100644
--- a/jOOQ-examples/jOOQ-spring-example/.settings/org.eclipse.jdt.core.prefs
+++ b/jOOQ-examples/jOOQ-spring-example/.settings/org.eclipse.jdt.core.prefs
@@ -5,9 +5,9 @@ org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annota
org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@@ -106,7 +106,7 @@ org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disa
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.formatter.align_type_members_on_columns=true
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=48
@@ -191,7 +191,6 @@ org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
org.eclipse.jdt.core.formatter.indentation.size=4
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
diff --git a/jOOQ-examples/jOOQ-spring-example/pom.xml b/jOOQ-examples/jOOQ-spring-example/pom.xml
index dbb2424350..2a32b20ec7 100644
--- a/jOOQ-examples/jOOQ-spring-example/pom.xml
+++ b/jOOQ-examples/jOOQ-spring-example/pom.xml
@@ -97,6 +97,26 @@
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 2.3.2
+
+ true
+ 1024m
+ 256m
+ UTF-8
+ 1.8
+ 1.8
+ true
+ lines,vars,source
+
+
+
+
+
+
+
+
+
-
+
-
+
+
-
- H2
-
+
+ H2
+
diff --git a/jOOQ-examples/jOOQ-spring-example/src/test/java/org/jooq/example/TransactionTest.java b/jOOQ-examples/jOOQ-spring-example/src/test/java/org/jooq/example/TransactionTest.java
index 0e8ae81b9b..0dd9d4a84e 100644
--- a/jOOQ-examples/jOOQ-spring-example/src/test/java/org/jooq/example/TransactionTest.java
+++ b/jOOQ-examples/jOOQ-spring-example/src/test/java/org/jooq/example/TransactionTest.java
@@ -44,8 +44,11 @@ import static org.jooq.example.db.h2.Tables.BOOK;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import java.util.concurrent.atomic.AtomicBoolean;
+
import org.jooq.DSLContext;
import org.jooq.example.spring.BookService;
+import org.jooq.example.spring.SpringTransactionProvider;
import org.junit.After;
import org.junit.Assert;
@@ -74,6 +77,7 @@ public class TransactionTest {
@Autowired DSLContext dsl;
@Autowired DataSourceTransactionManager txMgr;
+ @Autowired SpringTransactionProvider txProvider;
@Autowired BookService books;
@After
@@ -127,4 +131,92 @@ public class TransactionTest {
assertEquals(4, dsl.fetchCount(BOOK));
assertTrue(rollback);
}
+
+ @Test
+ public void testjOOQTransactionsSimple() {
+ boolean rollback = false;
+
+ try {
+ dsl.transaction(c -> {
+
+ // This is a "bug". The same book is created twice, resulting in a
+ // constraint violation exception
+ for (int i = 0; i < 2; i++)
+ dsl.insertInto(BOOK)
+ .set(BOOK.ID, 5)
+ .set(BOOK.AUTHOR_ID, 1)
+ .set(BOOK.TITLE, "Book 5")
+ .execute();
+
+ Assert.fail();
+ });
+ }
+
+ // Upon the constraint violation, the transaction must already have been rolled back
+ catch (DataAccessException e) {
+ rollback = true;
+ }
+
+ assertEquals(4, dsl.fetchCount(BOOK));
+ assertTrue(rollback);
+ }
+
+ @Test
+ public void testjOOQTransactionsNested() {
+ AtomicBoolean rollback1 = new AtomicBoolean(false);
+ AtomicBoolean rollback2 = new AtomicBoolean(false);
+
+ try {
+
+ // If using Spring transactions, we don't need the c1 reference
+ dsl.transaction(c1 -> {
+
+ // The first insertion will work
+ dsl.insertInto(BOOK)
+ .set(BOOK.ID, 5)
+ .set(BOOK.AUTHOR_ID, 1)
+ .set(BOOK.TITLE, "Book 5")
+ .execute();
+
+ assertEquals(5, dsl.fetchCount(BOOK));
+
+ try {
+
+ // Nest transactions using Spring. This should create a savepoint, right here
+ // If using Spring transactions, we don't need the c2 reference
+ dsl.transaction(c2 -> {
+
+ // The second insertion shouldn't work
+ for (int i = 0; i < 2; i++)
+ dsl.insertInto(BOOK)
+ .set(BOOK.ID, 6)
+ .set(BOOK.AUTHOR_ID, 1)
+ .set(BOOK.TITLE, "Book 6")
+ .execute();
+
+ Assert.fail();
+ });
+ }
+
+ catch (DataAccessException e) {
+ rollback1.set(true);
+ }
+
+ // We should've rolled back to the savepoint
+ assertEquals(5, dsl.fetchCount(BOOK));
+
+ throw new org.jooq.exception.DataAccessException("Rollback");
+ });
+ }
+
+ // Upon the constraint violation, the transaction must already have been rolled back
+ catch (org.jooq.exception.DataAccessException e) {
+ assertEquals("Rollback", e.getMessage());
+ rollback2.set(true);
+ }
+
+ assertEquals(4, dsl.fetchCount(BOOK));
+ assertTrue(rollback2.get());
+ assertTrue(rollback2.get());
+ }
}