Richard Zowalla created OPENJPA-3008:
----------------------------------------
Summary: H2 test profile loses committed data when H2 closes the
database between EntityManagerFactories
Key: OPENJPA-3008
URL: https://issues.apache.org/jira/browse/OPENJPA-3008
Project: OpenJPA
Issue Type: Bug
Components: jpa
Reporter: Richard Zowalla
The H2 test profile silently loses committed data, which makes tests fail far
away from the cause.
Mechanism:
1. Test cases such as those extending CriteriaTest build and close an
EntityManagerFactory per test. When DBCP builds the pool of a new factory it
opens a validation connection and really closes it
(BasicDataSource.validateConnectionFactory -> PoolableConnection.reallyClose),
so the H2 file database drops to zero connections and H2 closes the whole
database.
2. H2 compacts the store on every such close (MVStore.close -> FileStore.stop
-> RandomAccessStore.compactStore -> compactMoveChunks). That compaction trips
an assert in org.h2.mvstore.RandomAccessStore.moveChunkInside; surefire enables
assertions, and javap confirms RandomAccessStore has $assertionsDisabled, so
these are real assert statements.
3. The AssertionError aborts the close half way through compaction and commits
made shortly before it are lost.
openjpa-persistence-jdbc/target/database/openjpa-h2-database.trace.db records
it as:
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: IO Exception: "Closing"
[90028-232]
Caused by: org.h2.mvstore.MVStoreException: java.lang.AssertionError
[2.3.232/3]
at
org.h2.mvstore.RandomAccessStore.compactMoveChunks(RandomAccessStore.java:463)
at
org.h2.mvstore.RandomAccessStore.compactStore(RandomAccessStore.java:443)
at org.h2.mvstore.FileStore.stop(FileStore.java:275)
at org.h2.mvstore.MVStore.close(MVStore.java:643)
Caused by: java.lang.AssertionError
at
org.h2.mvstore.RandomAccessStore.moveChunkInside(RandomAccessStore.java:630)
Scale on a pristine master checkout (b4bfa57f0 era): the close failed 2398
times in a single run of
'TestEntityManagerFactoryTCK,TestGetNamedQueries,org.apache.openjpa.persistence.criteria.Test*'
and 3552 times in a wider selection. Which commits are lost depends on the
store layout, so the suite usually survives by luck; when a lost commit happens
to be the schema a later test class needs, that class fails with something
unrelated-looking. An observed example: TestMapJoinQuery creating MJ_DEPT
successfully and then failing with 'Table "MJ_DEPT" not found' (42S02) in its
own setUp moments later, with no DROP TABLE anywhere in the run.
Fix: add DB_CLOSE_DELAY=-1 to the test-h2 connection URL in pom.xml so the
database stays open for the lifetime of the test JVM instead of being closed
and reopened once per EntityManagerFactory. No close means no compaction and no
lost commits. Appending options to connection.url is the established pattern
(the Derby profile already uses ;create=true). As a side effect the selection
above runs in about 30 seconds instead of several minutes of MVStore fsync
churn.
The broken assert is H2's bug, not OpenJPA's; disabling assertions globally
would also hide OpenJPA's own. This may well be behind other unexplained H2
flakiness in the suite.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)