[
https://issues.apache.org/jira/browse/OPENJPA-3016?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18126731#comment-18126731
]
ASF subversion and git services commented on OPENJPA-3016:
----------------------------------------------------------
Commit af2c545eea1f2abcd411590c8bae8aa7ad9dd0de in openjpa's branch
refs/heads/OPENJPA-3016 from Richard Zowalla
[ https://gitbox.apache.org/repos/asf?p=openjpa.git;h=af2c545ee ]
[OPENJPA-3016] Release the EntityManager when a criteria test's setUp fails
junit.framework.TestCase.runBare() calls setUp() outside its try/finally:
setUp();
try { runTest(); } finally { tearDown(); }
so a failure in setUp() skips tearDown() altogether. CriteriaTest.setUp()
opens an EntityManager, and a subclass such as TestMultiselect then begins a
transaction in its own setUp() to clear the tables, which makes the store
manager retain a JDBC connection for the rest of that transaction. When that
step failed, the EntityManager and its connection were never released, and
because the criteria base classes keep the EntityManagerFactory in a static
field shared by every test class of their hierarchy the leaked connections
accumulated in one pool.
The test profiles size that pool at MaxTotal=10 with MaxWait=10s, so about a
dozen such failures emptied it and every later test in the same JVM failed
with
PersistenceException: Cannot get a connection, pool error Timeout waiting
for idle object, maxWaitDuration=PT9.999990575S
rather than with its own problem - which is how one broken schema
synchronisation turned into 174 failures and 185 errors in the scheduled
Databases run, with TestMultiselect spending 170 seconds purely on pool
timeouts.
AbstractCriteriaTestCase.runBare() now runs setUp() inside the guarded block
and calls tearDown() exactly once either way, which is what JUnit 4 does for
@Before/@After. For that to help, every criteria base class has to release
what setUp() opened, so the release sequence is hoisted into
AbstractCriteriaTestCase.releaseResources(): close the EntityManager, clear
the audited SQL, close the EntityManagerFactory, drop the references, each
step in its own finally so that a failure releasing one resource cannot leave
the next one open. CriteriaTest, EmbeddableDomainTestCase and
JoinDomainTestCase all delegate to it; previously only one of the three was
hardened, and EmbeddableDomainTestCase did not even reach
AbstractCriteriaTestCase.tearDown().
TestEmbeddableCriteria deliberately keeps its factory open for the whole
class, because rebuilding it would re-run buildSchema(SchemaAction='drop,add')
over the embeddable domain once per test method, and it did so by counting
test methods in setUp() and closing the factory in tearDown() only on the
last one. With tearDown() now running after a failed setUp() as well, that
counter would stop advancing at the first failure and the factory would never
be closed again, so the methods are counted in tearDown() instead, the count
is taken from the class rather than hard coded, and the EntityManager is
released on every method regardless.
This is deliberately a fix to the test infrastructure and not a larger pool
or a longer wait, either of which would only postpone the symptom.
TestSetUpFailureReleasesConnection drives three probes. Fourteen of them -
more than the pool holds - fail in setUp() after taking a connection in a
transaction that writes, and, unlike a real criteria test, release only their
own EntityManager so that one factory and one pool survive all fourteen; the
test affirms after each probe that its EntityManager was closed and at the
end that the pool still hands out a connection. A second probe closes
cleanly but throws out of EntityManager.close(), and affirms that the factory
was closed all the same. A third repeats the first failure in the
EmbeddableDomainTestCase hierarchy. The probes live in SetUpFailureProbes
rather than nested in the Test* class, or surefire reports their deliberate
failures as failures of the build whenever the criteria package is selected
by path.
Without the runBare() change, the first probe and the EmbeddableDomainTestCase
probe fail immediately:
junit.framework.AssertionFailedError: probe 0 left the EntityManager its
setUp() opened behind, so the connection it retained never went back to
the pool
and with that assertion removed as well, so that the probes keep leaking, the
loop reproduces the CI symptom directly - a later probe no longer gets a
connection at all:
org.apache.openjpa.persistence.PersistenceException: Cannot get a
connection, pool error Timeout waiting for idle object,
maxWaitDuration=PT9.999993S
Verified: the whole criteria package, 544 tests, no failures, on Derby and on
H2 (-Dtest-h2).
> Criteria tests fail on MariaDB and exhaust the connection pool;
> TestPessimisticLocks fails on PostgreSQL
> --------------------------------------------------------------------------------------------------------
>
> Key: OPENJPA-3016
> URL: https://issues.apache.org/jira/browse/OPENJPA-3016
> Project: OpenJPA
> Issue Type: Bug
> Components: jpa
> Reporter: Richard Zowalla
> Priority: Major
>
> The first scheduled run of the Databases workflow (OPENJPA-3011) was red: run
> 38204987477 of 12 Oct 2026 on master.
> check success
> build (Java 21, test-mysql-docker) success
> build (Java 21, test-postgresql-docker) failure
> build (Java 21, test-mariadb-docker) failure
> PostgreSQL 11: 197 tests, 1 failure,
> org.apache.openjpa.persistence.lockmgr.TestPessimisticLocks.
> MariaDB 11.8: the criteria package fails in bulk, starting about three
> minutes into the run, e.g.
> TestTypesafeCriteria 124 run, 45 failures, 70 errors
> TestMetaModelTypesafeCriteria 29 run, 10 failures, 11 errors
> TestTypeSafeCondExpression 55 run, 9 failures, 27 errors
> TestSubqueries 28 run, 13 failures, 15 errors
> TestQueryByExample 7 run, 1 failure, 6 errors
> and later, after those failures, the connection pool is exhausted:
> org.apache.openjpa.persistence.PersistenceException: Cannot get a
> connection, pool error Timeout waiting for idle object,
> maxWaitDuration=PT9.999990575S
> Caused by: java.util.NoSuchElementException: Timeout waiting for idle object
> TestMultiselect then reports 28 errors in 170 seconds, all of them connection
> timeouts.
> The ordering suggests the pool exhaustion is a consequence rather than the
> cause: the criteria tests fail first for some dictionary reason, and the
> failures leak connections until the pool is empty. That needs confirming, and
> both the dictionary failures and the leak are worth fixing - a test whose
> failure path leaks a connection turns one red test into a red suite.
> To reproduce, start the server yourself, since the docker profiles do not
> start containers during mvn test:
> docker run -d --name ojpa-maria -e MARIADB_DATABASE=openjpatst -e
> MARIADB_ROOT_PASSWORD=openjpatst -p 3306:3306 mariadb:11.8
> mvn -Ptest-mariadb-docker -pl openjpa-persistence-jdbc -am test
> -Dtest='org/apache/openjpa/persistence/criteria/Test*.java'
--
This message was sent by Atlassian Jira
(v8.20.10#820010)