diff --git a/jdo/identity/pom.xml b/jdo/identity/pom.xml
index e6e8ec4c..8dd7fc88 100644
--- a/jdo/identity/pom.xml
+++ b/jdo/identity/pom.xml
@@ -26,6 +26,11 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs
datanucleus-api-jdo
[${api.jdo.min.version}, ${api.jdo.max.version})
+
+ com.github.zabetak
+ jdbc-faulty
+ 2.0
+
diff --git a/jdo/identity/src/test/org/datanucleus/tests/ValueGeneratorRandomFailureTest.java b/jdo/identity/src/test/org/datanucleus/tests/ValueGeneratorRandomFailureTest.java
new file mode 100644
index 00000000..b59748f7
--- /dev/null
+++ b/jdo/identity/src/test/org/datanucleus/tests/ValueGeneratorRandomFailureTest.java
@@ -0,0 +1,101 @@
+/**********************************************************************
+Copyright (c) 2004 Andy Jefferson and others. All rights reserved.
+Licensed 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.
+
+Contributors :
+ 2025 Stamatis Zampetakis - Test reproducing a connection leak when failures occur during value generation
+***********************************************************************/
+package org.datanucleus.tests;
+
+import com.github.zabetak.jdbc.faulty.ExceptionFault;
+import com.github.zabetak.jdbc.faulty.FaultyJDBCDriver;
+import org.datanucleus.samples.valuegeneration.TableGeneratorItem;
+
+import javax.jdo.PersistenceManager;
+import javax.jdo.Transaction;
+import java.util.Properties;
+
+/**
+ * Test value generators in the presence of random failures when calling {@link java.sql.Connection} methods.
+ */
+public class ValueGeneratorRandomFailureTest extends JDOPersistenceTestCase
+{
+ private static Properties userProperties() {
+ Properties factoryProperties = TestHelper.getFactoryProperties(1, null);
+ String url = factoryProperties.getProperty("datanucleus.ConnectionURL");
+ // Add the faulty proxy in front of the regular JDBC driver
+ String faultyURL = url.replace("jdbc", "jdbc:faulty");
+ Properties userProps = new Properties();
+ userProps.put("datanucleus.connectionURL", faultyURL);
+ return userProps;
+ }
+
+ public ValueGeneratorRandomFailureTest(String name) {
+ super(name, userProperties());
+ }
+
+ /**
+ * In normal circumstances, the test should finish normally even though there are some occasional errors during
+ * commit. Due to the connection leak, the test currently fails (most often with lock timeout exceptions).
+ */
+ public void testTableGeneratorWithFailureOnCommitFinishesWithoutErrors()
+ {
+ try {
+ for (int i = 0; i < 100; i++) {
+ PersistenceManager pm = pmf.getPersistenceManager();
+ Transaction tx = pm.currentTransaction();
+ try {
+ tx.begin();
+ // Generate a random exception on 10% of the calls to Connection#commit
+ FaultyJDBCDriver.addFault("ex-fault-1", new ExceptionFault(0.1, "commit"));
+ pm.makePersistent(new TableGeneratorItem("Item_" + i));
+ FaultyJDBCDriver.clearFaults();
+ tx.commit();
+ }
+ catch(Exception e)
+ {
+ // If it is the artificially generated faulty exception ignore it and continue
+ // otherwise stop and propagate it
+ if (!isFaultyException(e)) {
+ throw e;
+ }
+ }
+ finally
+ {
+ if (tx.isActive()) {
+ tx.rollback();
+ }
+ pm.close();
+ }
+ }
+ }
+ finally
+ {
+ // Remove all registered faults
+ FaultyJDBCDriver.clearFaults();
+ // Clean out any created data
+ clean(TableGeneratorItem.class);
+ }
+ }
+
+ private static boolean isFaultyException(Throwable e) {
+ if (e == null) {
+ return false;
+ }
+ if (e.getMessage() != null && "Random exception generated by jdbc-faulty".equals(e.getMessage())) {
+ return true;
+ }
+ return isFaultyException(e.getCause());
+ }
+
+}
\ No newline at end of file