diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration.java index 992dbea54b5..dd157c21495 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration.java @@ -51,17 +51,21 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; */ @Configuration @ConditionalOnClass(EmbeddedDatabaseType.class) -@Import(DataSourceInitialization.class) @EnableConfigurationProperties(DataSourceProperties.class) public class DataSourceAutoConfiguration { public static final String CONFIGURATION_PREFIX = "spring.datasource"; + @Autowired + private DataSourceProperties properties; + @Autowired(required = false) private DataSource dataSource; - @Autowired - private DataSourceProperties properties; + @Bean + public DataSourceInitializer dataSourceAutoConfigurationInitializer() { + return new DataSourceInitializer(); + } /** * Determines if the {@code dataSource} being used by Spring was created from diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceInitialization.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceInitialization.java deleted file mode 100644 index d1d7a0b5bc2..00000000000 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceInitialization.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2012-2013 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.jdbc; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import javax.annotation.PostConstruct; -import javax.sql.DataSource; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationListener; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.io.Resource; -import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils; -import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; -import org.springframework.util.StringUtils; - -/** - * @author Dave Syer - * @since 1.1 - */ -@Configuration -@EnableConfigurationProperties(DataSourceProperties.class) -public class DataSourceInitialization { - - private static Log logger = LogFactory.getLog(DataSourceInitialization.class); - - @Autowired(required=false) - private DataSource dataSource; - - @Autowired - private ApplicationContext applicationContext; - - @Autowired - private DataSourceProperties properties; - - private boolean initialized = false; - - @Bean - public ApplicationListener dataSourceInitializedListener() { - return new DataSourceInitializedListener(); - } - - private void runSchemaScripts() { - String schema = this.properties.getSchema(); - if (schema == null) { - String platform = this.properties.getPlatform(); - schema = "classpath*:schema-" + platform + ".sql,"; - schema += "classpath*:schema.sql"; - } - if (runScripts(schema)) { - this.applicationContext.publishEvent(new DataSourceInitializedEvent( - this.dataSource)); - } - } - - private void runDataScripts() { - if (this.initialized) { - return; - } - String schema = this.properties.getData(); - if (schema == null) { - String platform = this.properties.getPlatform(); - schema = "classpath*:data-" + platform + ".sql,"; - schema += "classpath*:data.sql"; - } - runScripts(schema); - this.initialized = true; - } - - private boolean runScripts(String scripts) { - - if (this.dataSource == null) { - logger.debug("No DataSource found so not initializing"); - return false; - } - - List resources = getSchemaResources(scripts); - - boolean continueOnError = this.properties.isContinueOnError(); - boolean exists = false; - ResourceDatabasePopulator populator = new ResourceDatabasePopulator(); - for (Resource resource : resources) { - if (resource.exists()) { - exists = true; - populator.addScript(resource); - populator.setContinueOnError(continueOnError); - } - } - populator.setSeparator(this.properties.getSeparator()); - - if (exists) { - DatabasePopulatorUtils.execute(populator, this.dataSource); - } - - return exists; - - } - - private List getSchemaResources(String schema) { - List resources = new ArrayList(); - for (String schemaLocation : StringUtils.commaDelimitedListToStringArray(schema)) { - try { - resources.addAll(Arrays.asList(this.applicationContext - .getResources(schemaLocation))); - } - catch (IOException ex) { - throw new IllegalStateException("Unable to load resource from " - + schemaLocation, ex); - } - } - return resources; - } - - @SuppressWarnings("serial") - public static class DataSourceInitializedEvent extends ApplicationEvent { - - public DataSourceInitializedEvent(DataSource source) { - super(source); - } - - } - - private class DataSourceInitializedListener implements - ApplicationListener { - - // Keep this in the nested class so that it doesn't have to be called before the - // listener is instantiated (ordering problems otherwise) - @PostConstruct - protected void initialize() { - boolean initialize = DataSourceInitialization.this.properties.isInitialize(); - if (!initialize) { - logger.debug("Initialization disabled (not running DDL scripts)"); - return; - } - runSchemaScripts(); - } - - @Override - public void onApplicationEvent(DataSourceInitializedEvent event) { - runDataScripts(); - } - - } - -} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceInitializedEvent.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceInitializedEvent.java new file mode 100644 index 00000000000..3dc61df7666 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceInitializedEvent.java @@ -0,0 +1,43 @@ +/* + * Copyright 2012-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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.jdbc; + +import javax.sql.DataSource; + +import org.springframework.context.ApplicationEvent; + +/** + * {@link ApplicationEvent} used internally to trigger {@link DataSource} initialization. + * Initialization can occur when {@literal schema-*.sql} files are executed or when + * external libraries (e.g. JPA) initialize the database. + * + * @author Dave Syer + * @see DataSourceInitializer + * @since 1.1.0 + */ +@SuppressWarnings("serial") +public class DataSourceInitializedEvent extends ApplicationEvent { + + /** + * Create a new {@link DataSourceInitializedEvent}. + * @param source the source {@link DataSource}. + */ + public DataSourceInitializedEvent(DataSource source) { + super(source); + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceInitializer.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceInitializer.java new file mode 100644 index 00000000000..6a233c63049 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceInitializer.java @@ -0,0 +1,138 @@ +/* + * Copyright 2012-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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.jdbc; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.PostConstruct; +import javax.sql.DataSource; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationListener; +import org.springframework.core.io.Resource; +import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils; +import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.util.StringUtils; + +/** + * Bean to handle {@link DataSource} initialization by running {@literal schema-*.sql} on + * {@link PostConstruct} and and {@literal data-*.sql} SQL scripts on a + * {@link DataSourceInitializedEvent}. + * + * @author Dave Syer + * @author Phillip Webb + * @since 1.1.0 + * @see DataSourceAutoConfiguration + */ +class DataSourceInitializer implements ApplicationListener { + + private static Log logger = LogFactory.getLog(DataSourceInitializer.class); + + @Autowired + private ApplicationContext applicationContext; + + @Autowired(required = false) + private DataSource dataSource; + + @Autowired + private DataSourceProperties properties; + + private boolean initialized = false; + + @PostConstruct + protected void initialize() { + if (!this.properties.isInitialize()) { + logger.debug("Initialization disabled (not running DDL scripts)"); + return; + } + if (this.dataSource == null) { + logger.debug("No DataSource found so not initializing"); + return; + } + runSchemaScripts(); + } + + private void runSchemaScripts() { + List scripts = getScripts(this.properties.getSchema(), "schema"); + if (!scripts.isEmpty()) { + runScripts(scripts); + this.applicationContext.publishEvent(new DataSourceInitializedEvent( + this.dataSource)); + } + } + + @Override + public void onApplicationEvent(DataSourceInitializedEvent event) { + // NOTE the even can happen more than once and + // the event datasource if not used here + if (!this.initialized) { + runDataScripts(); + this.initialized = true; + } + } + + private void runDataScripts() { + List scripts = getScripts(this.properties.getData(), "data"); + runScripts(scripts); + } + + private List getScripts(String locations, String fallback) { + if (locations == null) { + String platform = this.properties.getPlatform(); + locations = "classpath*:" + fallback + "-" + platform + ".sql,"; + locations += "classpath*:" + fallback + ".sql"; + } + return getResources(locations); + } + + private List getResources(String locations) { + List resources = new ArrayList(); + for (String location : StringUtils.commaDelimitedListToStringArray(locations)) { + try { + for (Resource resource : this.applicationContext.getResources(location)) { + if (resource.exists()) { + resources.add(resource); + } + } + } + catch (IOException ex) { + throw new IllegalStateException("Unable to load resource from " + + location, ex); + } + } + return resources; + } + + private void runScripts(List resources) { + if (resources.isEmpty()) { + return; + } + ResourceDatabasePopulator populator = new ResourceDatabasePopulator(); + populator.setContinueOnError(this.properties.isContinueOnError()); + populator.setSeparator(this.properties.getSeparator()); + for (Resource resource : resources) { + populator.addScript(resource); + } + DatabasePopulatorUtils.execute(populator, this.dataSource); + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/DataSourceInitializedPublisher.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/DataSourceInitializedPublisher.java index 751421c382e..0444565f6ff 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/DataSourceInitializedPublisher.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/DataSourceInitializedPublisher.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2013 the original author or authors. + * Copyright 2012-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. @@ -16,21 +16,38 @@ package org.springframework.boot.autoconfigure.orm.jpa; +import java.util.Map; + import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.boot.autoconfigure.jdbc.DataSourceInitialization.DataSourceInitializedEvent; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.GenericBeanDefinition; +import org.springframework.boot.autoconfigure.jdbc.DataSourceInitializedEvent; import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; +import org.springframework.core.type.AnnotationMetadata; -public class DataSourceInitializedPublisher implements BeanPostProcessor { +/** + * {@link BeanPostProcessor} used to fire {@link DataSourceInitializedEvent}s. Should only + * be registered via the inner {@link Registrar} class. + * + * @author Dave Syer + * @since 1.1.0 + */ +class DataSourceInitializedPublisher implements BeanPostProcessor { @Autowired private ApplicationContext applicationContext; + private DataSource dataSource; + private JpaProperties properties; + @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { @@ -44,10 +61,48 @@ public class DataSourceInitializedPublisher implements BeanPostProcessor { // Normally this will be the right DataSource this.dataSource = (DataSource) bean; } - if (bean instanceof EntityManagerFactory && this.dataSource != null) { + if (bean instanceof JpaProperties) { + this.properties = (JpaProperties) bean; + } + if (bean instanceof EntityManagerFactory && this.dataSource != null + && isInitializingDatabase()) { this.applicationContext.publishEvent(new DataSourceInitializedEvent( this.dataSource)); } return bean; } -} \ No newline at end of file + + private boolean isInitializingDatabase() { + Map hibernate = this.properties + .getHibernateProperties(this.dataSource); + if (hibernate.containsKey("hibernate.hbm2ddl.auto")) { + return true; + } + return false; + } + + /** + * {@link ImportBeanDefinitionRegistrar} to register the + * {@link DataSourceInitializedPublisher} without causing early bean instantiation + * issues. + */ + static class Registrar implements ImportBeanDefinitionRegistrar { + + private static final String BEAN_NAME = "dataSourceInitializedPublisher"; + + @Override + public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, + BeanDefinitionRegistry registry) { + if (!registry.containsBeanDefinition(BEAN_NAME)) { + GenericBeanDefinition beanDefinition = new GenericBeanDefinition(); + beanDefinition.setBeanClass(DataSourceInitializedPublisher.class); + beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); + // We don't need this one to be post processed otherwise it can cause a + // cascade of bean instantiation that we would rather avoid. + beanDefinition.setSynthetic(true); + registry.registerBeanDefinition(BEAN_NAME, beanDefinition); + } + } + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration.java index 370dce5e2a5..9804de176d3 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration.java @@ -25,23 +25,17 @@ import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.GenericBeanDefinition; import org.springframework.boot.autoconfigure.AutoConfigurationPackages; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.DataSourceInitializedRegistrar; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.context.annotation.Primary; -import org.springframework.core.type.AnnotationMetadata; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.JpaVendorAdapter; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; @@ -61,7 +55,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter * @author Oliver Gierke */ @EnableConfigurationProperties(JpaProperties.class) -@Import(DataSourceInitializedRegistrar.class) +@Import(DataSourceInitializedPublisher.Registrar.class) public abstract class JpaBaseConfiguration implements BeanFactoryAware { private ConfigurableListableBeanFactory beanFactory; @@ -155,24 +149,4 @@ public abstract class JpaBaseConfiguration implements BeanFactoryAware { } - protected static class DataSourceInitializedRegistrar implements - ImportBeanDefinitionRegistrar { - - private static final String BEAN_NAME = "dataSourceInitializedPublisher"; - - @Override - public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, - BeanDefinitionRegistry registry) { - if (!registry.containsBeanDefinition(BEAN_NAME)) { - GenericBeanDefinition beanDefinition = new GenericBeanDefinition(); - beanDefinition.setBeanClass(DataSourceInitializedPublisher.class); - beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); - // We don't need this one to be post processed otherwise it can cause a - // cascade of bean instantiation that we would rather avoid. - beanDefinition.setSynthetic(true); - registry.registerBeanDefinition(BEAN_NAME, beanDefinition); - } - } - } - } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaProperties.java index 463802315c9..322fec888e3 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaProperties.java @@ -139,19 +139,6 @@ public class JpaProperties { return this.ddlAuto; } - private String getActualDdlAuto(Map existing, - DataSource dataSource) { - String ddlAuto = this.ddlAuto != null ? this.ddlAuto - : getDefaultDdlAuto(dataSource); - if (!isAlreadyProvided(existing, "hbm2ddl.auto") && !"none".equals(ddlAuto)) { - return ddlAuto; - } - if (isAlreadyProvided(existing, "hbm2ddl.auto")) { - return existing.get("hibernate.hbm2ddl.auto"); - } - return "none"; - } - public void setDdlAuto(String ddlAuto) { this.ddlAuto = ddlAuto; } @@ -167,7 +154,7 @@ public class JpaProperties { result.put("hibernate.ejb.naming_strategy", DEFAULT_NAMING_STRATEGY.getName()); } - String ddlAuto = getActualDdlAuto(existing, dataSource); + String ddlAuto = getOrDeduceDdlAuto(existing, dataSource); if (StringUtils.hasText(ddlAuto) && !"none".equals(ddlAuto)) { result.put("hibernate.hbm2ddl.auto", ddlAuto); } @@ -177,8 +164,17 @@ public class JpaProperties { return result; } - private boolean isAlreadyProvided(Map existing, String key) { - return existing.containsKey("hibernate." + key); + private String getOrDeduceDdlAuto(Map existing, + DataSource dataSource) { + String ddlAuto = (this.ddlAuto != null ? this.ddlAuto + : getDefaultDdlAuto(dataSource)); + if (!isAlreadyProvided(existing, "hbm2ddl.auto") && !"none".equals(ddlAuto)) { + return ddlAuto; + } + if (isAlreadyProvided(existing, "hbm2ddl.auto")) { + return existing.get("hibernate.hbm2ddl.auto"); + } + return "none"; } private String getDefaultDdlAuto(DataSource dataSource) { @@ -188,6 +184,10 @@ public class JpaProperties { return "none"; } + private boolean isAlreadyProvided(Map existing, String key) { + return existing.containsKey("hibernate." + key); + } + } } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceInitializationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceInitializerTests.java similarity index 91% rename from spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceInitializationTests.java rename to spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceInitializerTests.java index 7151d7f75d3..f1b7bf44aed 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceInitializationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceInitializerTests.java @@ -13,9 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; -import static org.junit.Assert.*; +package org.springframework.boot.autoconfigure.jdbc; import java.util.Random; @@ -31,11 +30,16 @@ import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.util.ClassUtils; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + /** + * Tests for {@link DataSourceInitializer}. + * * @author Dave Syer - * */ -public class DataSourceInitializationTests { +public class DataSourceInitializerTests { private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); @@ -50,15 +54,15 @@ public class DataSourceInitializationTests { @After public void restore() { EmbeddedDatabaseConnection.override = null; - if (context!=null) { - context.close(); + if (this.context != null) { + this.context.close(); } } @Test public void testDefaultDataSourceDoesNotExists() throws Exception { - this.context.register(DataSourceInitialization.class, - PropertyPlaceholderAutoConfiguration.class); + this.context.register(DataSourceInitializer.class, + PropertyPlaceholderAutoConfiguration.class, DataSourceProperties.class); this.context.refresh(); assertEquals(0, this.context.getBeanNamesForType(DataSource.class).length); } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/AbstractJpaAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/AbstractJpaAutoConfigurationTests.java index e3eaf2ea065..a20592b681c 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/AbstractJpaAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/AbstractJpaAutoConfigurationTests.java @@ -30,7 +30,7 @@ import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; -import org.springframework.boot.autoconfigure.jdbc.DataSourceInitialization; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.test.City; @@ -191,7 +191,7 @@ public abstract class AbstractJpaAutoConfigurationTests { protected void setupTestConfiguration(Class configClass) { this.context.register(configClass, EmbeddedDataSourceConfiguration.class, - DataSourceInitialization.class, + DataSourceAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class, getAutoConfigureClass()); } diff --git a/spring-boot-docs/src/main/asciidoc/howto.adoc b/spring-boot-docs/src/main/asciidoc/howto.adoc index e77ab487e2d..fc30d498bc2 100644 --- a/spring-boot-docs/src/main/asciidoc/howto.adoc +++ b/spring-boot-docs/src/main/asciidoc/howto.adoc @@ -1165,7 +1165,9 @@ and `data-${platform}.sql` files (if present), where it to the vendor name of the database (`hsqldb`, `h2`, `oracle`, `mysql`, `postgresql` etc.). Spring Boot enables the failfast feature of the Spring JDBC initializer by default, so if the scripts cause exceptions the application will fail -to start. The script locations can be changed by setting `spring.datasource.schema` and `spring.datasource.data`, and neither location will be processed if `spring.datasource.initialize=false`. +to start. The script locations can be changed by setting `spring.datasource.schema` and +`spring.datasource.data`, and neither location will be processed if +`spring.datasource.initialize=false`. To disable the failfast you can set `spring.datasource.continueOnError=true`. This can be useful once an application has matured and been deployed a few times, since the scripts