H2内存测试数据库已关闭,尽管设置了'DB_CLOSE_ON_EXIT=FALSE'。

5 浏览
0 Comments

H2内存测试数据库已关闭,尽管设置了'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: 数据库已关闭(要禁用在VM关闭时自动关闭,请在数据库URL中添加“;DB_CLOSE_ON_EXIT=FALSE”)[90121-197]

问题出在我的Spring Data AuditProvider上,具体是这一行:

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

只有在执行整个测试套件时才会出现错误,而仅运行这个测试类时不会出现。

这是我使用的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    : 对名为'inMemoryDatabaseShutdownExecutor'的bean执行销毁方法失败:org.h2.jdbc.JdbcSQLException: 数据库已关闭(要禁用在VM关闭时自动关闭,请在数据库URL中添加“;DB_CLOSE_ON_EXIT=FALSE”)

但我没有得到PersistenceException和堆栈跟踪。

0
0 Comments

H2内存测试数据库关闭了,尽管设置了'DB_CLOSE_ON_EXIT=FALSE'。这个问题的出现原因是当使用了(SpringJUnit4ClassRunner.class)注解的多个单元测试类时,每个测试类都会启动Spring,然后Spring会启动JPA。如果多个测试类并行运行,每个测试类都会创建、然后删除相同的内存数据库,可能会出现并发问题。为了防止JUnit为连续的测试重用相同的“上下文”,您可能还需要将surefire的reuseForks参数设置为false。

解决方法:

- 为每个测试类创建一个独立的内存数据库,以避免并发问题。

- 设置surefire的reuseForks参数为false,确保JUnit不会为连续的测试重用相同的“上下文”。

对于这个问题的解决方法,可以在测试类上添加如下注解:

@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)

这将确保在每个测试类运行完毕后,Spring上下文被清除,从而避免了并发问题。

0
0 Comments

在使用内存数据库时,应该避免使用"DB_CLOSE_ON_EXIT=FALSE",而应该只使用"DB_CLOSE_DELAY=-1"。如果你使用的是Maven,需要将"forkCount"设置为0,以确保所有的单元测试在相同的虚拟机中运行。根据测试结果来看,更换连接字符串和添加插件配置并没有改变任何结果。在命令行中运行测试是正常的,但在Eclipse中运行测试却会报错。对此,很抱歉我无法解释为什么在Eclipse中的集成与通常的Maven构建如此不同。这也是为什么我更喜欢使用Netbeans或IntelliJ的原因:它们与Maven或Gradle的集成更好。同时,对于"DB_CLOSE_ON_EXIT=FALSE"的使用,根据文档的解释,如果你配置了嵌入式数据库的连接URL,需要确保禁用数据库的自动关闭。

0