问题描述
我正在使用h2嵌入式数据库,其定义如下:
I am using h2 embedded database which is defined like that:
<jdbc:embedded-database id="embeddedDatasource" type="h2"/>
我有两个测试:
@RunWith(SpringJunit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration("classpath:h2-context.xml")
class Test1 {...}
@RunWith(SpringJunit4ClassRunner.class)
@ContextConfiguration("classpath:h2-context.xml")
class Test2 {...}
执行完所有测试后,我会在日志中看到:
After all tests execution I do see in the log:
* 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 ...
因此,实体经理关闭所有测试执行后的每个上下文。我知道spring会缓存上下文文件,所以我猜h2 bean在两次测试中共享。
So, the entity manager is closed for each context after all tests execution. I know that spring caches context files, so I guess h2 bean is shared across two tests.
问题是:有时我会得到奇怪的异常喜欢:
The problem is: sometimes I get weird exception like:
H2EmbeddedDatabaseConfigurer: Could not shutdown embedded database
jrg.h2.jdbc.JDBCSQLException: The database has been closed [90098-179]
我如何解决这个问题?
这是我到目前为止所发现的:
This is what I've found so far:Spring’s embedded H2 datasource and DB_CLOSE_ON_EXIT
推荐答案
因为您使用的是Spring Framework 3.1。 4,你可能会看到Spring和H2之间的冲突结果都试图关闭数据库。
Since you are using Spring Framework 3.1.4, you are potentially seeing the results of a clash between Spring and H2 both attempting to shut down the database.
这个冲突已在Spring Framework 4.0.3中解决(请参阅详细信息)。
This conflict has been addressed in Spring Framework 4.0.3 (see SPR-11573 for details).
具体来说,从Spring 4.0.3开始,使用连接URL创建嵌入式H2数据库:jdbc:h2:mem :%S; DB_CLOSE_DELAY = -1; DB_CLOSE_ON_EXIT =假
。 %s是数据库的名称(例如,testdb)。
Specifically, as of Spring 4.0.3, embedded H2 databases are created with the connection URL: "jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false"
. The "%s" is the name of the database (e.g., "testdb").
因此,如果您希望嵌入式H2数据库在版本上具有相同的行为在4.0.3之前的Spring中,您需要使用类似于上面的连接URL手动创建 DataSource
。
Thus, if you would like the same behavior for your embedded H2 database on versions of Spring prior to 4.0.3, you will need to manually create the DataSource
using a connection URL similar to the one above.
是的, Spring TestContext Framework 缓存测试和测试类中的 ApplicationContext
。但是......嵌入式H2数据库的 DataSource
在这些上下文中共享不。相反,在上面概述的场景中,最终得到2 DataSource
s - 每个上下文中有一个,并且都指向相同的内存数据库。
Yes, the Spring TestContext Framework caches ApplicationContext
s across tests and test classes. But... the DataSource
for the embedded H2 database is not shared across those contexts. Rather, in the scenario you've outlined above, you end up with 2 DataSource
s -- one in each context and both referring to the same in-memory database.
Sooo,现在我想到了,你遇到的问题更可能是因为你的 ApplicationContext
s正试图关闭完全相同的内存数据库。要解决该问题,您可以考虑在每次创建嵌入式数据库时为其定义唯一名称。有关此主题的详细信息,请阅读以下有关已在Spring 4.2中解决的JIRA问题,但仍包含有关如何在4.2之前实现相同目标的提示。
Sooo, now that I think about it, the problem you are encountering is more likely due to the fact that both of your ApplicationContext
s are attempting to shut down the exact same in-memory database. To solve that problem, you can consider defining a unique name for the embedded database, each time it's created. For details on this topic, please read the following to JIRA issues which have been resolved for Spring 4.2 but still contain tips on how to achieve the same goals before 4.2.
- https://jira.spring.io/browse/SPR-12835
- https://jira.spring.io/browse/SPR-8849
问候,
Sam
这篇关于Spring测试多次关闭嵌入式数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!