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

时间:2015-06-12 14:56:17

标签: java spring h2 spring-test embedded-database

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

<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 {...}

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

* 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在两个测试中共享。

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

H2EmbeddedDatabaseConfigurer: Could not shutdown embedded database
jrg.h2.jdbc.JDBCSQLException: The database has been closed [90098-179]

我该如何解决?

这是我到目前为止所发现的: Spring’s embedded H2 datasource and DB_CLOSE_ON_EXIT

1 个答案:

答案 0 :(得分:5)

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

此问题已在Spring Framework 4.0.3中得到解决(有关详细信息,请参阅SPR-11573)。

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

因此,如果您希望在4.0.3之前的Spring版本上嵌入H2数据库具有相同的行为,则需要使用类似于上面的连接URL手动创建DataSource。 / p>

  

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

是的, Spring TestContext Framework 在测试和测试类中缓存ApplicationContext。但是......嵌入式H2数据库的DataSource在这些上下文中共享。相反,在上面概述的场景中,最终得到2 DataSource s - 每个上下文中有一个,并且都指向相同的内存数据库。

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

此致

萨姆