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 Oliver Gierke
* @author Juergen Hoeller * @author Juergen Hoeller
* @author Sam Brannen
* @since 3.0 * @since 3.0
*/ */
final class H2EmbeddedDatabaseConfigurer extends AbstractEmbeddedDatabaseConfigurer { 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 * @return the configurer
* @throws ClassNotFoundException if H2 is not on the classpath * @throws ClassNotFoundException if H2 is not on the classpath
*/ */
@ -57,7 +58,7 @@ final class H2EmbeddedDatabaseConfigurer extends AbstractEmbeddedDatabaseConfigu
@Override @Override
public void configureConnectionProperties(ConnectionProperties properties, String databaseName) { public void configureConnectionProperties(ConnectionProperties properties, String databaseName) {
properties.setDriverClass(this.driverClass); 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.setUsername("sa");
properties.setPassword(""); 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 Dave Syer
* @author Juergen Hoeller * @author Juergen Hoeller
* @author Chris Beams * @author Chris Beams
* @author Sam Brannen
*/ */
public class JdbcNamespaceIntegrationTests { public class JdbcNamespaceIntegrationTests {
@Rule @Rule
public ExpectedException expected = ExpectedException.none(); public ExpectedException expected = ExpectedException.none();
@Test
public void testCreateEmbeddedDatabase() throws Exception {
Assume.group(TestGroup.LONG_RUNNING);
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( @Test
"org/springframework/jdbc/config/jdbc-config.xml"); public void createEmbeddedDatabase() throws Exception {
assertCorrectSetup(context, "dataSource", "h2DataSource", "derbyDataSource"); Assume.group(TestGroup.LONG_RUNNING);
context.close(); assertCorrectSetup("jdbc-config.xml", "dataSource", "h2DataSource", "derbyDataSource");
} }
@Test @Test
public void testCreateEmbeddedDatabaseAgain() throws Exception { public void createEmbeddedDatabaseAgain() throws Exception {
// If Derby isn't cleaned up properly this will fail... // If Derby isn't cleaned up properly this will fail...
Assume.group(TestGroup.LONG_RUNNING); Assume.group(TestGroup.LONG_RUNNING);
assertCorrectSetup("jdbc-config.xml", "derbyDataSource");
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"org/springframework/jdbc/config/jdbc-config.xml");
assertCorrectSetup(context, "derbyDataSource");
context.close();
} }
@Test @Test
public void testCreateWithResourcePattern() throws Exception { public void createWithResourcePattern() throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( assertCorrectSetup("jdbc-config-pattern.xml", "dataSource");
"org/springframework/jdbc/config/jdbc-config-pattern.xml");
assertCorrectSetup(context, "dataSource");
context.close();
} }
@Test @Test
public void testCreateWithEndings() throws Exception { public void createWithEndings() throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( assertCorrectSetupAndCloseContext("jdbc-initialize-endings-config.xml", 2, "dataSource");
"org/springframework/jdbc/config/jdbc-initialize-endings-config.xml");
assertCorrectSetup(context, 2, "dataSource");
context.close();
} }
@Test @Test
public void testCreateWithEndingsNested() throws Exception { public void createWithEndingsNested() throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( assertCorrectSetupAndCloseContext("jdbc-initialize-endings-nested-config.xml", 2, "dataSource");
"org/springframework/jdbc/config/jdbc-initialize-endings-nested-config.xml");
assertCorrectSetup(context, 2, "dataSource");
context.close();
} }
@Test @Test
public void testCreateAndDestroy() throws Exception { public void createAndDestroy() throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( ClassPathXmlApplicationContext context = context("jdbc-destroy-config.xml");
"org/springframework/jdbc/config/jdbc-destroy-config.xml");
try { try {
DataSource dataSource = context.getBean(DataSource.class); DataSource dataSource = context.getBean(DataSource.class);
JdbcTemplate template = new JdbcTemplate(dataSource); JdbcTemplate template = new JdbcTemplate(dataSource);
assertEquals(1, template.queryForInt("select count(*) from T_TEST")); assertNumRowsInTestTable(template, 1);
context.getBean(DataSourceInitializer.class).destroy(); context.getBean(DataSourceInitializer.class).destroy();
expected.expect(BadSqlGrammarException.class); // Table has been dropped expected.expect(BadSqlGrammarException.class); // Table has been dropped
assertEquals(1, template.queryForInt("select count(*) from T_TEST")); assertNumRowsInTestTable(template, 1);
} }
finally { finally {
context.close(); context.close();
@ -111,16 +95,15 @@ public class JdbcNamespaceIntegrationTests {
} }
@Test @Test
public void testCreateAndDestroyNested() throws Exception { public void createAndDestroyNestedWithHsql() throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( ClassPathXmlApplicationContext context = context("jdbc-destroy-nested-config.xml");
"org/springframework/jdbc/config/jdbc-destroy-nested-config.xml");
try { try {
DataSource dataSource = context.getBean(DataSource.class); DataSource dataSource = context.getBean(DataSource.class);
JdbcTemplate template = new JdbcTemplate(dataSource); JdbcTemplate template = new JdbcTemplate(dataSource);
assertEquals(1, template.queryForInt("select count(*) from T_TEST")); assertNumRowsInTestTable(template, 1);
context.getBean(EmbeddedDatabaseFactoryBean.class).destroy(); context.getBean(EmbeddedDatabaseFactoryBean.class).destroy();
expected.expect(BadSqlGrammarException.class); // Table has been dropped expected.expect(BadSqlGrammarException.class); // Table has been dropped
assertEquals(1, template.queryForInt("select count(*) from T_TEST")); assertNumRowsInTestTable(template, 1);
} }
finally { finally {
context.close(); context.close();
@ -128,14 +111,34 @@ public class JdbcNamespaceIntegrationTests {
} }
@Test @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(); DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(factory).loadBeanDefinitions(new ClassPathResource( 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", "firstDataSource", factory);
assertBeanPropertyValueOf("databaseName", "secondDataSource", factory); assertBeanPropertyValueOf("databaseName", "secondDataSource", factory);
} }
private ClassPathXmlApplicationContext context(String file) {
return new ClassPathXmlApplicationContext(file, getClass());
}
private void assertBeanPropertyValueOf(String propertyName, String expected, DefaultListableBeanFactory factory) { private void assertBeanPropertyValueOf(String propertyName, String expected, DefaultListableBeanFactory factory) {
BeanDefinition bean = factory.getBeanDefinition(expected); BeanDefinition bean = factory.getBeanDefinition(expected);
PropertyValue value = bean.getPropertyValues().getPropertyValue(propertyName); PropertyValue value = bean.getPropertyValues().getPropertyValue(propertyName);
@ -143,22 +146,26 @@ public class JdbcNamespaceIntegrationTests {
assertThat(value.getValue().toString(), is(expected)); assertThat(value.getValue().toString(), is(expected));
} }
private void assertCorrectSetup(ConfigurableApplicationContext context, String... dataSources) { private void assertNumRowsInTestTable(JdbcTemplate template, int count) {
assertCorrectSetup(context, 1, dataSources); 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 { try {
for (String dataSourceName : dataSources) { for (String dataSourceName : dataSources) {
DataSource dataSource = context.getBean(dataSourceName, DataSource.class); DataSource dataSource = context.getBean(dataSourceName, DataSource.class);
JdbcTemplate template = new JdbcTemplate(dataSource); JdbcTemplate template = new JdbcTemplate(dataSource);
assertEquals(count, template.queryForInt("select count(*) from T_TEST")); assertNumRowsInTestTable(template, count);
} }
} }
finally { finally {
context.close(); 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>