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 -&gt; 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]

Reply via email to