Set DB_CLOSE_ON_EXIT=false in H2EmbeddedDbConfig

This commit sets the DB_CLOSE_ON_EXIT flag to false for embedded H2
databases loaded using H2EmbeddedDatabaseConfigurer (i.e., via Spring's
<jdbc:embedded-database /> XML namespace, EmbeddedDatabaseBuilder,
EmbeddedDatabaseFactory, and EmbeddedDatabaseFactoryBean).

Issue: SPR-11573
This commit is contained in:
Sam Brannen 2014-03-19 01:22:46 +01:00
parent dc6d67510d
commit 8aefcb9a55
3 changed files with 70 additions and 48 deletions

View File

@ -26,6 +26,7 @@ import org.springframework.util.ClassUtils;
*
* @author Oliver Gierke
* @author Juergen Hoeller
* @author Sam Brannen
* @since 3.0
*/
final class H2EmbeddedDatabaseConfigurer extends AbstractEmbeddedDatabaseConfigurer {
@ -36,7 +37,7 @@ final class H2EmbeddedDatabaseConfigurer extends AbstractEmbeddedDatabaseConfigu
/**
* Get the singleton {@link H2EmbeddedDatabaseConfigurer} instance.
* Get the singleton {@code H2EmbeddedDatabaseConfigurer} instance.
* @return the configurer
* @throws ClassNotFoundException if H2 is not on the classpath
*/
@ -57,7 +58,7 @@ final class H2EmbeddedDatabaseConfigurer extends AbstractEmbeddedDatabaseConfigu
@Override
public void configureConnectionProperties(ConnectionProperties properties, String databaseName) {
properties.setDriverClass(this.driverClass);
properties.setUrl(String.format("jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1", databaseName));
properties.setUrl(String.format("jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false", databaseName));
properties.setUsername("sa");
properties.setPassword("");
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -42,68 +42,52 @@ import static org.junit.Assert.*;
* @author Dave Syer
* @author Juergen Hoeller
* @author Chris Beams
* @author Sam Brannen
*/
public class JdbcNamespaceIntegrationTests {
@Rule
public ExpectedException expected = ExpectedException.none();
@Test
public void testCreateEmbeddedDatabase() throws Exception {
Assume.group(TestGroup.LONG_RUNNING);
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"org/springframework/jdbc/config/jdbc-config.xml");
assertCorrectSetup(context, "dataSource", "h2DataSource", "derbyDataSource");
context.close();
@Test
public void createEmbeddedDatabase() throws Exception {
Assume.group(TestGroup.LONG_RUNNING);
assertCorrectSetup("jdbc-config.xml", "dataSource", "h2DataSource", "derbyDataSource");
}
@Test
public void testCreateEmbeddedDatabaseAgain() throws Exception {
public void createEmbeddedDatabaseAgain() throws Exception {
// If Derby isn't cleaned up properly this will fail...
Assume.group(TestGroup.LONG_RUNNING);
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"org/springframework/jdbc/config/jdbc-config.xml");
assertCorrectSetup(context, "derbyDataSource");
context.close();
assertCorrectSetup("jdbc-config.xml", "derbyDataSource");
}
@Test
public void testCreateWithResourcePattern() throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"org/springframework/jdbc/config/jdbc-config-pattern.xml");
assertCorrectSetup(context, "dataSource");
context.close();
public void createWithResourcePattern() throws Exception {
assertCorrectSetup("jdbc-config-pattern.xml", "dataSource");
}
@Test
public void testCreateWithEndings() throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"org/springframework/jdbc/config/jdbc-initialize-endings-config.xml");
assertCorrectSetup(context, 2, "dataSource");
context.close();
public void createWithEndings() throws Exception {
assertCorrectSetupAndCloseContext("jdbc-initialize-endings-config.xml", 2, "dataSource");
}
@Test
public void testCreateWithEndingsNested() throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"org/springframework/jdbc/config/jdbc-initialize-endings-nested-config.xml");
assertCorrectSetup(context, 2, "dataSource");
context.close();
public void createWithEndingsNested() throws Exception {
assertCorrectSetupAndCloseContext("jdbc-initialize-endings-nested-config.xml", 2, "dataSource");
}
@Test
public void testCreateAndDestroy() throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"org/springframework/jdbc/config/jdbc-destroy-config.xml");
public void createAndDestroy() throws Exception {
ClassPathXmlApplicationContext context = context("jdbc-destroy-config.xml");
try {
DataSource dataSource = context.getBean(DataSource.class);
JdbcTemplate template = new JdbcTemplate(dataSource);
assertEquals(1, template.queryForInt("select count(*) from T_TEST"));
assertNumRowsInTestTable(template, 1);
context.getBean(DataSourceInitializer.class).destroy();
expected.expect(BadSqlGrammarException.class); // Table has been dropped
assertEquals(1, template.queryForInt("select count(*) from T_TEST"));
assertNumRowsInTestTable(template, 1);
}
finally {
context.close();
@ -111,16 +95,15 @@ public class JdbcNamespaceIntegrationTests {
}
@Test
public void testCreateAndDestroyNested() throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"org/springframework/jdbc/config/jdbc-destroy-nested-config.xml");
public void createAndDestroyNestedWithHsql() throws Exception {
ClassPathXmlApplicationContext context = context("jdbc-destroy-nested-config.xml");
try {
DataSource dataSource = context.getBean(DataSource.class);
JdbcTemplate template = new JdbcTemplate(dataSource);
assertEquals(1, template.queryForInt("select count(*) from T_TEST"));
assertNumRowsInTestTable(template, 1);
context.getBean(EmbeddedDatabaseFactoryBean.class).destroy();
expected.expect(BadSqlGrammarException.class); // Table has been dropped
assertEquals(1, template.queryForInt("select count(*) from T_TEST"));
assertNumRowsInTestTable(template, 1);
}
finally {
context.close();
@ -128,14 +111,34 @@ public class JdbcNamespaceIntegrationTests {
}
@Test
public void testMultipleDataSourcesHaveDifferentDatabaseNames() throws Exception {
public void createAndDestroyNestedWithH2() throws Exception {
ClassPathXmlApplicationContext context = context("jdbc-destroy-nested-config-h2.xml");
try {
DataSource dataSource = context.getBean(DataSource.class);
JdbcTemplate template = new JdbcTemplate(dataSource);
assertNumRowsInTestTable(template, 1);
context.getBean(EmbeddedDatabaseFactoryBean.class).destroy();
expected.expect(BadSqlGrammarException.class); // Table has been dropped
assertNumRowsInTestTable(template, 1);
}
finally {
context.close();
}
}
@Test
public void multipleDataSourcesHaveDifferentDatabaseNames() throws Exception {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(factory).loadBeanDefinitions(new ClassPathResource(
"org/springframework/jdbc/config/jdbc-config-multiple-datasources.xml"));
"jdbc-config-multiple-datasources.xml", getClass()));
assertBeanPropertyValueOf("databaseName", "firstDataSource", factory);
assertBeanPropertyValueOf("databaseName", "secondDataSource", factory);
}
private ClassPathXmlApplicationContext context(String file) {
return new ClassPathXmlApplicationContext(file, getClass());
}
private void assertBeanPropertyValueOf(String propertyName, String expected, DefaultListableBeanFactory factory) {
BeanDefinition bean = factory.getBeanDefinition(expected);
PropertyValue value = bean.getPropertyValues().getPropertyValue(propertyName);
@ -143,22 +146,26 @@ public class JdbcNamespaceIntegrationTests {
assertThat(value.getValue().toString(), is(expected));
}
private void assertCorrectSetup(ConfigurableApplicationContext context, String... dataSources) {
assertCorrectSetup(context, 1, dataSources);
private void assertNumRowsInTestTable(JdbcTemplate template, int count) {
assertEquals(count, template.queryForObject("select count(*) from T_TEST", Integer.class).intValue());
}
private void assertCorrectSetup(ConfigurableApplicationContext context, int count, String... dataSources) {
private void assertCorrectSetup(String file, String... dataSources) {
assertCorrectSetupAndCloseContext(file, 1, dataSources);
}
private void assertCorrectSetupAndCloseContext(String file, int count, String... dataSources) {
ConfigurableApplicationContext context = context(file);
try {
for (String dataSourceName : dataSources) {
DataSource dataSource = context.getBean(dataSourceName, DataSource.class);
JdbcTemplate template = new JdbcTemplate(dataSource);
assertEquals(count, template.queryForInt("select count(*) from T_TEST"));
assertNumRowsInTestTable(template, count);
}
}
finally {
context.close();
}
}
}

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd">
<jdbc:embedded-database id="dataSource" type="H2">
<jdbc:script location="classpath:org/springframework/jdbc/config/db-schema.sql" execution="INIT"/>
<jdbc:script location="classpath:org/springframework/jdbc/config/db-test-data.sql" execution="INIT"/>
<jdbc:script location="classpath:org/springframework/jdbc/config/db-drops.sql" execution="DESTROY"/>
</jdbc:embedded-database>
</beans>