web-dev-qa-db-ja.com

H2インメモリテストDBは、 'DB_CLOSE_ON_EXIT = FALSE'にもかかわらず閉じられました

例外で失敗するいくつかの短い単体テストがあります:

javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not prepare statement
::
Caused by: org.hibernate.exception.GenericJDBCException: could not prepare statement
::
Caused by: org.h2.jdbc.JdbcSQLException: Database is already closed (to disable automatic closing at VM shutdown, add ";DB_CLOSE_ON_EXIT=FALSE" to the db URL) [90121-197]

ソースは私のSpring Data AuditProviderで、具体的には次の行です。

user = entityManager.createNamedQuery("findUserByUsernameAndTenant", User.class)
        .setParameter("tenant", TenantService.DEFAULT_TENANT_ID)
        .setParameter("username", UserService.USER_SYSTEM).getSingleResult();

エラーが発生するのはonlyテストスイート全体を実行するときであり、このテストクラスのみを実行するときではありません。

ここで私が使用しているTestRunnerなど:

@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
@Rollback
public class MyTest {

それが私のデータソースURLです。

spring.datasource.url: 'jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE'

「DB_CLOSE_ON_EXIT」は問題を解決していないようです。ここで何が起こっているのでしょうか?

更新:

これはEclipseでテストを実行しているときにのみ発生しますが、コマンドラインで実行されることを認識しました。私は時々得ますが:

o.s.b.f.support.DisposableBeanAdapter    : Invocation of destroy method failed on bean with name 'inMemoryDatabaseShutdownExecutor': org.h2.jdbc.JdbcSQLException: Database is already closed (to disable automatic closing at VM shutdown, add ";DB_CLOSE_ON_EXIT=FALSE" to the db URL)

しかし、PersistenceExceptionとスタックトレースを取得できません。

4
Benjamin Maurer

DB_CLOSE_DELAYのみを使用してください。

インメモリデータベースの場合、DB_CLOSE_ON_EXIT=FALSEを使用しないでください。DB_CLOSE_DELAY=-1のみを使用してください。参照 http://www.h2database.com/html/features.html#in_memory_databases

したがって、データソースは次のようになります。

spring.datasource.url: 'jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1'

単体テストが並列プロセスで実行されることも可能です。それらがすべて同じVMで実行されていることを確認してください。

Mavenを使用する場合は、forkCount0に設定します。

<plugin>
  <groupId>org.Apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.22.0</version>
  <configuration>
    <forkCount>0</forkCount>
  </configuration>
</plugin>
5

あなたのさまざまなユニットテストクラスはすべて@RunWith(SpringJUnit4ClassRunner.class)で注釈されていると思いますか?

その場合、開始されたすべてのテストクラスはSpringを起動し、SpringはJPAを起動します。 multipleテストクラスが並行して実行され、各クラスが[〜#〜] same [〜#〜]インメモリデータベースを作成してから削除する場合、いくつかの並行性の問題があります。

JUnitがconsecutiveテストに同じ 'コンテキスト'を再利用しないようにするために、surefire reuseForksパラメータをfalseに設定する必要がある場合もあります。

1
TacheDeChoco