春季测试多次关闭嵌入式数据库

Vad*_*huk 2 java spring h2 spring-test embedded-database

我正在使用h2嵌入式数据库,其定义如下:

<jdbc:embedded-database id="embeddedDatasource" type="h2"/>
Run Code Online (Sandbox Code Playgroud)

我有两个测试:

@RunWith(SpringJunit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration("classpath:h2-context.xml")
class Test1 {...}

@RunWith(SpringJunit4ClassRunner.class)
@ContextConfiguration("classpath:h2-context.xml")
class Test2 {...}
Run Code Online (Sandbox Code Playgroud)

执行完所有测试后,我确实在日志中看到:

* Closing org.springframework.context.support.GenericApplicationContext
* Closing org.springframework.web.context.support.GenericWebApplicationContext
* Closing JPA EntitiManagerFactory for Persistance unit ...
* Closing JPA EntitiManagerFactory for Persistance unit ...
Run Code Online (Sandbox Code Playgroud)

因此,在执行完所有测试之后,将为每个上下文关闭实体管理器。我知道spring会缓存上下文文件,所以我猜H2 bean在两个测试之间共享。

问题是:有时我会收到奇怪的异常,例如:

H2EmbeddedDatabaseConfigurer: Could not shutdown embedded database
jrg.h2.jdbc.JDBCSQLException: The database has been closed [90098-179]
Run Code Online (Sandbox Code Playgroud)

我该如何解决?

到目前为止,这是我发现的内容: Spring的嵌入式H2数据源和DB_CLOSE_ON_EXIT

Sam*_*nen 5

由于您使用的是Spring Framework 3.1.4,因此可能会看到试图关闭数据库的Spring和H2之间发生冲突的结果。

Spring Framework 4.0.3中已解决了此冲突(有关详细信息,请参阅SPR-11573)。

具体来说,从Spring 4.0.3开始,将使用连接URL:创建嵌入式H2数据库"jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false"。“%s”是数据库的名称(例如“ testdb”)。

因此,如果您希望在4.0.3之前的Spring版本上对嵌入式H2数据库使用相同的行为,则需要DataSource使用与上述类似的连接URL 手动创建。

因此,在执行完所有测试之后,将为每个上下文关闭实体管理器。我知道spring会缓存上下文文件,所以我猜H2 bean在两个测试之间共享。

是的,Spring TestContext FrameworkApplicationContext在测试和测试类之间缓存。但是... DataSource嵌入式H2数据库的不在这些上下文之间共享。相反,在上面概述的场景中,您最终要花2 DataSources的时间-在每种情况下一个,并且都引用同一个内存数据库。

太好了,现在考虑到这一点,您遇到的问题更有可能是由于您ApplicationContext的两个都试图关闭完全相同的内存数据库。为了解决该问题,您可以考虑在每次创建嵌入式数据库时为其定义一个唯一的名称。有关此主题的详细信息,请阅读JIRA问题的以下内容,这些问题已在Spring 4.2中解决,但仍包含有关如何在4.2之前实现相同目标的提示。

问候,

山姆