diff --git a/spring-boot-devtools/pom.xml b/spring-boot-devtools/pom.xml
index 8c274f5957..53a73f6509 100644
--- a/spring-boot-devtools/pom.xml
+++ b/spring-boot-devtools/pom.xml
@@ -112,6 +112,17 @@
spring-webmvc
test
+
+ org.apache.derby
+ derby
+ test
+
+
+ org.apache.derby
+ derbyclient
+ ${derby.version}
+ test
+
org.apache.tomcat.embed
tomcat-embed-core
@@ -122,6 +133,11 @@
websocket-client
test
+
+ org.hsqldb
+ hsqldb
+ test
+
org.postgresql
postgresql
diff --git a/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/DevToolsDataSourceAutoConfiguration.java b/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/DevToolsDataSourceAutoConfiguration.java
index 2c867b5013..6ca4905fbc 100644
--- a/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/DevToolsDataSourceAutoConfiguration.java
+++ b/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/DevToolsDataSourceAutoConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2016 the original author or authors.
+ * Copyright 2012-2017 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,7 +42,6 @@ import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ConfigurationCondition;
import org.springframework.core.type.AnnotatedTypeMetadata;
-import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.orm.jpa.AbstractEntityManagerFactoryBean;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
@@ -85,12 +84,6 @@ public class DevToolsDataSourceAutoConfiguration {
static final class NonEmbeddedInMemoryDatabaseShutdownExecutor
implements DisposableBean {
- private static final Set IN_MEMORY_DRIVER_CLASS_NAMES = new HashSet(
- Arrays.asList("org.apache.derby.jdbc.EmbeddedDriver", "org.h2.Driver",
- "org.h2.jdbcx.JdbcDataSource", "org.hsqldb.jdbcDriver",
- "org.hsqldb.jdbc.JDBCDriver",
- "org.hsqldb.jdbc.pool.JDBCXADataSource"));
-
private final DataSource dataSource;
private final DataSourceProperties dataSourceProperties;
@@ -109,9 +102,42 @@ public class DevToolsDataSourceAutoConfiguration {
}
private boolean dataSourceRequiresShutdown() {
- return IN_MEMORY_DRIVER_CLASS_NAMES
- .contains(this.dataSourceProperties.determineDriverClassName())
- && (!(this.dataSource instanceof EmbeddedDatabase));
+ for (InMemoryDatabase inMemoryDatabase : InMemoryDatabase.values()) {
+ if (inMemoryDatabase.matches(this.dataSourceProperties)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static enum InMemoryDatabase {
+
+ DERBY(null, "org.apache.derby.jdbc.EmbeddedDriver"),
+
+ H2("jdbc:h2:mem:", "org.h2.Driver", "org.h2.jdbcx.JdbcDataSource"),
+
+ HQSQLDB("jdbc:hsqldb:mem:", "org.hsqldb.jdbcDriver",
+ "org.hsqldb.jdbc.JDBCDriver",
+ "org.hsqldb.jdbc.pool.JDBCXADataSource");
+
+ private final String urlPrefix;
+
+ private final Set driverClassNames;
+
+ InMemoryDatabase(String urlPrefix, String... driverClassNames) {
+ this.urlPrefix = urlPrefix;
+ this.driverClassNames = new HashSet(
+ Arrays.asList(driverClassNames));
+ }
+
+ boolean matches(DataSourceProperties properties) {
+ String url = properties.getUrl();
+ return (url == null || this.urlPrefix == null
+ || url.startsWith(this.urlPrefix))
+ && this.driverClassNames
+ .contains(properties.determineDriverClassName());
+ }
+
}
}
diff --git a/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/AbstractDevToolsDataSourceAutoConfigurationTests.java b/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/AbstractDevToolsDataSourceAutoConfigurationTests.java
index 2c7b86aece..33b0bff999 100644
--- a/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/AbstractDevToolsDataSourceAutoConfigurationTests.java
+++ b/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/AbstractDevToolsDataSourceAutoConfigurationTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2016 the original author or authors.
+ * Copyright 2012-2017 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.
@@ -95,8 +95,17 @@ public abstract class AbstractDevToolsDataSourceAutoConfigurationTests {
return statement;
}
+ protected final ConfigurableApplicationContext createContext(Class>... classes) {
+ return this.createContext(null, classes);
+ }
+
protected final ConfigurableApplicationContext createContext(String driverClassName,
Class>... classes) {
+ return this.createContext(driverClassName, null, classes);
+ }
+
+ protected final ConfigurableApplicationContext createContext(String driverClassName,
+ String url, Class>... classes) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(classes);
context.register(DevToolsDataSourceAutoConfiguration.class);
@@ -104,14 +113,13 @@ public abstract class AbstractDevToolsDataSourceAutoConfigurationTests {
EnvironmentTestUtils.addEnvironment(context,
"spring.datasource.driver-class-name:" + driverClassName);
}
+ if (url != null) {
+ EnvironmentTestUtils.addEnvironment(context, "spring.datasource.url:" + url);
+ }
context.refresh();
return context;
}
- protected final ConfigurableApplicationContext createContext(Class>... classes) {
- return this.createContext(null, classes);
- }
-
@Configuration
static class SingleDataSourceConfiguration {
diff --git a/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/DevToolsPooledDataSourceAutoConfigurationTests.java b/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/DevToolsPooledDataSourceAutoConfigurationTests.java
index 8d109951c3..043c6b237f 100644
--- a/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/DevToolsPooledDataSourceAutoConfigurationTests.java
+++ b/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/DevToolsPooledDataSourceAutoConfigurationTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2016 the original author or authors.
+ * Copyright 2012-2017 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.
@@ -57,4 +57,70 @@ public class DevToolsPooledDataSourceAutoConfigurationTests
verify(statement, times(0)).execute("SHUTDOWN");
}
+ @Test
+ public void h2ServerIsNotShutdown() throws SQLException {
+ ConfigurableApplicationContext context = createContext("org.h2.Driver",
+ "jdbc:h2:hsql://localhost", DataSourceAutoConfiguration.class,
+ DataSourceSpyConfiguration.class);
+ Statement statement = configureDataSourceBehaviour(
+ context.getBean(DataSource.class));
+ context.close();
+ verify(statement, times(0)).execute("SHUTDOWN");
+ }
+
+ @Test
+ public void inMemoryh2IsShutdown() throws SQLException {
+ ConfigurableApplicationContext context = createContext("org.h2.Driver",
+ "jdbc:h2:mem:test", DataSourceAutoConfiguration.class,
+ DataSourceSpyConfiguration.class);
+ Statement statement = configureDataSourceBehaviour(
+ context.getBean(DataSource.class));
+ context.close();
+ verify(statement, times(1)).execute("SHUTDOWN");
+ }
+
+ @Test
+ public void hsqlServerIsNotShutdown() throws SQLException {
+ ConfigurableApplicationContext context = createContext("org.hsqldb.jdbcDriver",
+ "jdbc:hsqldb:hsql://localhost", DataSourceAutoConfiguration.class,
+ DataSourceSpyConfiguration.class);
+ Statement statement = configureDataSourceBehaviour(
+ context.getBean(DataSource.class));
+ context.close();
+ verify(statement, times(0)).execute("SHUTDOWN");
+ }
+
+ @Test
+ public void inMemoryHsqlIsShutdown() throws SQLException {
+ ConfigurableApplicationContext context = createContext("org.hsqldb.jdbcDriver",
+ "jdbc:hsqldb:mem:test", DataSourceAutoConfiguration.class,
+ DataSourceSpyConfiguration.class);
+ Statement statement = configureDataSourceBehaviour(
+ context.getBean(DataSource.class));
+ context.close();
+ verify(statement, times(1)).execute("SHUTDOWN");
+ }
+
+ @Test
+ public void derbyClientIsNotShutdown() throws SQLException {
+ ConfigurableApplicationContext context = createContext(
+ "org.apache.derby.jdbc.ClientDriver", "jdbc:derby://localhost",
+ DataSourceAutoConfiguration.class, DataSourceSpyConfiguration.class);
+ Statement statement = configureDataSourceBehaviour(
+ context.getBean(DataSource.class));
+ context.close();
+ verify(statement, times(0)).execute("SHUTDOWN");
+ }
+
+ @Test
+ public void inMemoryDerbyIsShutdown() throws SQLException {
+ ConfigurableApplicationContext context = createContext(
+ "org.apache.derby.jdbc.EmbeddedDriver", "jdbc:derby:memory:test",
+ DataSourceAutoConfiguration.class, DataSourceSpyConfiguration.class);
+ Statement statement = configureDataSourceBehaviour(
+ context.getBean(DataSource.class));
+ context.close();
+ verify(statement, times(1)).execute("SHUTDOWN");
+ }
+
}