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)

Reply via email to