This is an automated email from the ASF dual-hosted git repository.
mweiler pushed a commit to branch main
in repository
https://gitbox.apache.org/repos/asf/incubator-kie-kogito-runtimes.git
The following commit(s) were added to refs/heads/main by this push:
new f5101b837d [incubator-kie-issues#2203] Ensure JDBC code is running in
a transactional context in Spring Boot (#4158)
f5101b837d is described below
commit f5101b837d6c82b2852d275e1a00dafd7ffbdac4
Author: Martin Weiler <[email protected]>
AuthorDate: Wed Jan 7 10:16:52 2026 -0700
[incubator-kie-issues#2203] Ensure JDBC code is running in a transactional
context in Spring Boot (#4158)
* [incubator-kie-issues#2203] Ensure JDBC code is running in a
transactional context in Spring Boot
* Add missing license header
* Disable tests for PostgreSQL persistence
---
.../springboot/JDBCProcessInstancesFactory.java | 5 +-
.../transactional_error_no_wait_state.bpmn | 147 +++++++++++++++++++++
.../kogito/it/TransactionalErrorHandlingTest.java | 40 ++++++
.../it/PostgreSQLTransactionalErrorHandlingIT.java | 14 ++
4 files changed, 205 insertions(+), 1 deletion(-)
diff --git
a/springboot/addons/persistence/jdbc/src/main/java/org/kie/kogito/persistence/springboot/JDBCProcessInstancesFactory.java
b/springboot/addons/persistence/jdbc/src/main/java/org/kie/kogito/persistence/springboot/JDBCProcessInstancesFactory.java
index 34c2e72344..565c61ba0e 100644
---
a/springboot/addons/persistence/jdbc/src/main/java/org/kie/kogito/persistence/springboot/JDBCProcessInstancesFactory.java
+++
b/springboot/addons/persistence/jdbc/src/main/java/org/kie/kogito/persistence/springboot/JDBCProcessInstancesFactory.java
@@ -26,6 +26,7 @@ import
org.kie.kogito.internal.process.runtime.HeadersPersistentConfig;
import org.kie.kogito.persistence.jdbc.AbstractProcessInstancesFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
+import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
import org.springframework.stereotype.Component;
@Component
@@ -36,7 +37,9 @@ public class JDBCProcessInstancesFactory extends
AbstractProcessInstancesFactory
@Value("${kogito.persistence.optimistic.lock:false}") Boolean lock,
@Value("${kogito.persistence.headers.enabled:false}") Boolean
headersEnabled,
@Value("${kogito.persistence.headers.excluded:}") List<String>
headersExcluded) {
- super(dataSource, lock, new HeadersPersistentConfig(headersEnabled,
headersExcluded));
+
+ // Wrap the original DataSource so operations use the transactional
Connection
+ super(new TransactionAwareDataSourceProxy(dataSource), lock, new
HeadersPersistentConfig(headersEnabled, headersExcluded));
}
}
diff --git
a/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-persistence-common/src/main/resources/transactional_error_no_wait_state.bpmn
b/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-persistence-common/src/main/resources/transactional_error_no_wait_state.bpmn
new file mode 100644
index 0000000000..298ced11d7
--- /dev/null
+++
b/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-persistence-common/src/main/resources/transactional_error_no_wait_state.bpmn
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+<bpmn2:definitions xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:bpsim="http://www.bpsim.org/schemas/1.0"
xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
xmlns:drools="http://www.jboss.org/drools" xmlns:xsi="xsi"
id="_d0wRoL9VED6lUejjYxs5Jw"
xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd
http://www.jboss.org/drools drools.xsd http://www [...]
+ <bpmn2:itemDefinition id="_failItem" structureRef="Boolean"/>
+ <bpmn2:collaboration id="_36FE0541-6C39-496D-BB3D-9F002B6F57F7"
name="Default Collaboration">
+ <bpmn2:participant id="_80857597-DF49-4149-851A-D907282E13E1" name="Pool
Participant" processRef="transactional_errors_no_wait_state"/>
+ </bpmn2:collaboration>
+ <bpmn2:process id="transactional_errors_no_wait_state"
drools:packageName="org.kie.kogito" drools:version="1.0" drools:adHoc="false"
name="transactional_errors_no_wait_state" isExecutable="true"
processType="Public">
+ <bpmn2:property id="fail" itemSubjectRef="_failItem" name="fail"/>
+ <bpmn2:sequenceFlow id="_75CD85AE-40AB-4D88-BF39-C22CA61DEAC9"
sourceRef="_530D47D5-4BE7-4E54-8F12-C225CB9B3529"
targetRef="_F44C0F61-F897-4D8F-884A-AEBFF906E5FD"/>
+ <bpmn2:sequenceFlow id="_20A1FF12-D2BF-4522-A23A-724F925A7584"
sourceRef="_9413B17A-F1C9-444F-978D-63EFA8CD4801"
targetRef="_530D47D5-4BE7-4E54-8F12-C225CB9B3529"/>
+ <bpmn2:sequenceFlow id="_4A571422-CE8A-4BAD-8D3B-CAD5F9DE07A7"
sourceRef="_48F366CD-9D0F-4E92-AA59-1638DCD5933B"
targetRef="_9413B17A-F1C9-444F-978D-63EFA8CD4801"/>
+ <bpmn2:scriptTask id="_9413B17A-F1C9-444F-978D-63EFA8CD4801"
name="ScriptTask 1" scriptFormat="http://www.java.com/java">
+ <bpmn2:extensionElements>
+ <drools:metaData name="elementname">
+ <drools:metaValue><![CDATA[ScriptTask 1]]></drools:metaValue>
+ </drools:metaData>
+ </bpmn2:extensionElements>
+ <bpmn2:incoming>_4A571422-CE8A-4BAD-8D3B-CAD5F9DE07A7</bpmn2:incoming>
+ <bpmn2:outgoing>_20A1FF12-D2BF-4522-A23A-724F925A7584</bpmn2:outgoing>
+ <bpmn2:script>System.out.println("This is a previous task to see if we
catch the error in this node");</bpmn2:script>
+ </bpmn2:scriptTask>
+ <bpmn2:endEvent id="_F44C0F61-F897-4D8F-884A-AEBFF906E5FD">
+ <bpmn2:incoming>_75CD85AE-40AB-4D88-BF39-C22CA61DEAC9</bpmn2:incoming>
+ </bpmn2:endEvent>
+ <bpmn2:scriptTask id="_530D47D5-4BE7-4E54-8F12-C225CB9B3529" name="It may
fail" scriptFormat="http://www.java.com/java">
+ <bpmn2:extensionElements>
+ <drools:metaData name="elementname">
+ <drools:metaValue><![CDATA[It may fail]]></drools:metaValue>
+ </drools:metaData>
+ </bpmn2:extensionElements>
+ <bpmn2:incoming>_20A1FF12-D2BF-4522-A23A-724F925A7584</bpmn2:incoming>
+ <bpmn2:outgoing>_75CD85AE-40AB-4D88-BF39-C22CA61DEAC9</bpmn2:outgoing>
+ <bpmn2:script>if(fail) {
+ throw new java.lang.RuntimeException("This is a controlled error... fail
without wait state -> true");
+}
+
+System.out.println("Congratulations there's not error!");</bpmn2:script>
+ </bpmn2:scriptTask>
+ <bpmn2:startEvent id="_48F366CD-9D0F-4E92-AA59-1638DCD5933B">
+ <bpmn2:outgoing>_4A571422-CE8A-4BAD-8D3B-CAD5F9DE07A7</bpmn2:outgoing>
+ </bpmn2:startEvent>
+ </bpmn2:process>
+ <bpmndi:BPMNDiagram>
+ <bpmndi:BPMNPlane bpmnElement="transactional_errors_no_wait_state">
+ <bpmndi:BPMNShape id="shape__48F366CD-9D0F-4E92-AA59-1638DCD5933B"
bpmnElement="_48F366CD-9D0F-4E92-AA59-1638DCD5933B">
+ <dc:Bounds height="56" width="56" x="104" y="131"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="shape__530D47D5-4BE7-4E54-8F12-C225CB9B3529"
bpmnElement="_530D47D5-4BE7-4E54-8F12-C225CB9B3529">
+ <dc:Bounds height="102" width="154" x="684" y="108"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="shape__F44C0F61-F897-4D8F-884A-AEBFF906E5FD"
bpmnElement="_F44C0F61-F897-4D8F-884A-AEBFF906E5FD">
+ <dc:Bounds height="56" width="56" x="918" y="131"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="shape__9413B17A-F1C9-444F-978D-63EFA8CD4801"
bpmnElement="_9413B17A-F1C9-444F-978D-63EFA8CD4801">
+ <dc:Bounds height="102" width="154" x="450" y="108"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge
id="edge_shape__48F366CD-9D0F-4E92-AA59-1638DCD5933B_to_shape__9413B17A-F1C9-444F-978D-63EFA8CD4801"
bpmnElement="_4A571422-CE8A-4BAD-8D3B-CAD5F9DE07A7">
+ <di:waypoint x="132" y="159"/>
+ <di:waypoint x="527" y="159"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge
id="edge_shape__9413B17A-F1C9-444F-978D-63EFA8CD4801_to_shape__530D47D5-4BE7-4E54-8F12-C225CB9B3529"
bpmnElement="_20A1FF12-D2BF-4522-A23A-724F925A7584">
+ <di:waypoint x="527" y="159"/>
+ <di:waypoint x="684" y="159"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge
id="edge_shape__530D47D5-4BE7-4E54-8F12-C225CB9B3529_to_shape__F44C0F61-F897-4D8F-884A-AEBFF906E5FD"
bpmnElement="_75CD85AE-40AB-4D88-BF39-C22CA61DEAC9">
+ <di:waypoint x="761" y="159"/>
+ <di:waypoint x="946" y="159"/>
+ </bpmndi:BPMNEdge>
+ </bpmndi:BPMNPlane>
+ </bpmndi:BPMNDiagram>
+ <bpmn2:relationship type="BPSimData">
+ <bpmn2:extensionElements>
+ <bpsim:BPSimData>
+ <bpsim:Scenario id="default" name="Simulationscenario">
+ <bpsim:ScenarioParameters/>
+ <bpsim:ElementParameters
elementRef="_48F366CD-9D0F-4E92-AA59-1638DCD5933B">
+ <bpsim:TimeParameters>
+ <bpsim:ProcessingTime>
+ <bpsim:NormalDistribution mean="0" standardDeviation="0"/>
+ </bpsim:ProcessingTime>
+ </bpsim:TimeParameters>
+ </bpsim:ElementParameters>
+ <bpsim:ElementParameters
elementRef="_530D47D5-4BE7-4E54-8F12-C225CB9B3529">
+ <bpsim:TimeParameters>
+ <bpsim:ProcessingTime>
+ <bpsim:NormalDistribution mean="0" standardDeviation="0"/>
+ </bpsim:ProcessingTime>
+ </bpsim:TimeParameters>
+ <bpsim:ResourceParameters>
+ <bpsim:Availability>
+ <bpsim:FloatingParameter value="0"/>
+ </bpsim:Availability>
+ <bpsim:Quantity>
+ <bpsim:FloatingParameter value="0"/>
+ </bpsim:Quantity>
+ </bpsim:ResourceParameters>
+ <bpsim:CostParameters>
+ <bpsim:UnitCost>
+ <bpsim:FloatingParameter value="0"/>
+ </bpsim:UnitCost>
+ </bpsim:CostParameters>
+ </bpsim:ElementParameters>
+ <bpsim:ElementParameters
elementRef="_9413B17A-F1C9-444F-978D-63EFA8CD4801">
+ <bpsim:TimeParameters>
+ <bpsim:ProcessingTime>
+ <bpsim:NormalDistribution mean="0" standardDeviation="0"/>
+ </bpsim:ProcessingTime>
+ </bpsim:TimeParameters>
+ <bpsim:ResourceParameters>
+ <bpsim:Availability>
+ <bpsim:FloatingParameter value="0"/>
+ </bpsim:Availability>
+ <bpsim:Quantity>
+ <bpsim:FloatingParameter value="0"/>
+ </bpsim:Quantity>
+ </bpsim:ResourceParameters>
+ <bpsim:CostParameters>
+ <bpsim:UnitCost>
+ <bpsim:FloatingParameter value="0"/>
+ </bpsim:UnitCost>
+ </bpsim:CostParameters>
+ </bpsim:ElementParameters>
+ </bpsim:Scenario>
+ </bpsim:BPSimData>
+ </bpmn2:extensionElements>
+ <bpmn2:source>_d0wRoL9VED6lUejjYxs5Jw</bpmn2:source>
+ <bpmn2:target>_d0wRoL9VED6lUejjYxs5Jw</bpmn2:target>
+ </bpmn2:relationship>
+</bpmn2:definitions>
\ No newline at end of file
diff --git
a/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-persistence-common/src/test/java/org/kie/kogito/it/TransactionalErrorHandlingTest.java
b/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-persistence-common/src/test/java/org/kie/kogito/it/TransactionalErrorHandlingTest.java
index 649b1c89f3..6eaa35f184 100644
---
a/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-persistence-common/src/test/java/org/kie/kogito/it/TransactionalErrorHandlingTest.java
+++
b/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-persistence-common/src/test/java/org/kie/kogito/it/TransactionalErrorHandlingTest.java
@@ -39,6 +39,7 @@ public abstract class TransactionalErrorHandlingTest {
private static final String MANAGEMENT_INSTANCE_PATH =
"/management/processes/{processId}/instances/{processInstanceId}";
private static final String ERRORS_PROCESS = "transactional_errors";
+ private static final String ERRORS_PROCESS_NO_WAIT_STATE =
"transactional_errors_no_wait_state";
static {
RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
@@ -169,4 +170,43 @@ public abstract class TransactionalErrorHandlingTest {
.statusCode(200)
.body("size()", is(0));
}
+
+ @Test
+ void testTransactionalProcessNoWaitStateSuccess() {
+ String pId = given().contentType(ContentType.JSON)
+ .when()
+ .body(Map.of("fail", false))
+ .post("/{processId}", ERRORS_PROCESS_NO_WAIT_STATE)
+ .then()
+ .statusCode(201)
+ .body("id", not(emptyOrNullString()))
+ .extract()
+ .path("id");
+ given()
+ .accept(ContentType.JSON)
+ .when()
+ .pathParam("processId", ERRORS_PROCESS_NO_WAIT_STATE)
+ .get("/{processId}")
+ .then()
+ .statusCode(200)
+ .body("size()", is(0));
+ }
+
+ @Test
+ void testTransactionalProcessNoWaitStateFailure() {
+ given().contentType(ContentType.JSON)
+ .when()
+ .body(Map.of("fail", true))
+ .post("/{processId}", ERRORS_PROCESS_NO_WAIT_STATE)
+ .then()
+ .statusCode(500);
+ given()
+ .accept(ContentType.JSON)
+ .when()
+ .pathParam("processId", ERRORS_PROCESS_NO_WAIT_STATE)
+ .get("/{processId}")
+ .then()
+ .statusCode(200)
+ .body("size()", is(0));
+ }
}
diff --git
a/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-postgresql/src/test/java/org/kie/kogito/it/PostgreSQLTransactionalErrorHandlingIT.java
b/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-postgresql/src/test/java/org/kie/kogito/it/PostgreSQLTransactionalErrorHandlingIT.java
index 27bbe119f3..ada5bfb72b 100644
---
a/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-postgresql/src/test/java/org/kie/kogito/it/PostgreSQLTransactionalErrorHandlingIT.java
+++
b/springboot/integration-tests/integration-tests-springboot-processes-persistence-it/integration-tests-springboot-processes-postgresql/src/test/java/org/kie/kogito/it/PostgreSQLTransactionalErrorHandlingIT.java
@@ -19,6 +19,8 @@
package org.kie.kogito.it;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
import
org.kie.kogito.testcontainers.springboot.PostgreSqlSpringBootTestResource;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;
@@ -26,4 +28,16 @@ import org.springframework.test.context.ContextConfiguration;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = KogitoSpringbootApplication.class)
@ContextConfiguration(initializers = PostgreSqlSpringBootTestResource.class)
public class PostgreSQLTransactionalErrorHandlingIT extends
TransactionalErrorHandlingTest {
+
+ @Test
+ @Disabled
+ void testTransactionalProcessNoWaitStateSuccess() {
+ return;
+ }
+
+ @Test
+ @Disabled
+ void testTransactionalProcessNoWaitStateFailure() {
+ return;
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]