Defer SQL initialization to fit with JPA better
Added 2 new spring.datasource.* properties ("data" like "schema", and "deferDdl" like the "spring.jpa.hibernate.*" flag). The SQL scripts are then run separately and the "data" ones are triggered by a new DataSourceInitializedEvent, which is also published by the Hibernate DDL schema export. Fixes gh-1006
This commit is contained in:
parent
efcbb32788
commit
49a09c807c
|
@ -16,16 +16,8 @@
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.jdbc;
|
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 javax.sql.DataSource;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -38,23 +30,18 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
||||||
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
|
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.ApplicationContext;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Condition;
|
import org.springframework.context.annotation.Condition;
|
||||||
import org.springframework.context.annotation.ConditionContext;
|
import org.springframework.context.annotation.ConditionContext;
|
||||||
import org.springframework.context.annotation.Conditional;
|
import org.springframework.context.annotation.Conditional;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.core.io.Resource;
|
|
||||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||||
import org.springframework.jdbc.core.JdbcOperations;
|
import org.springframework.jdbc.core.JdbcOperations;
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
|
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
|
||||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||||
import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils;
|
|
||||||
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link EnableAutoConfiguration Auto-configuration} for {@link DataSource}.
|
* {@link EnableAutoConfiguration Auto-configuration} for {@link DataSource}.
|
||||||
|
@ -64,73 +51,18 @@ import org.springframework.util.StringUtils;
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@ConditionalOnClass(EmbeddedDatabaseType.class)
|
@ConditionalOnClass(EmbeddedDatabaseType.class)
|
||||||
|
@Import(DataSourceInitialization.class)
|
||||||
@EnableConfigurationProperties(DataSourceProperties.class)
|
@EnableConfigurationProperties(DataSourceProperties.class)
|
||||||
public class DataSourceAutoConfiguration {
|
public class DataSourceAutoConfiguration {
|
||||||
|
|
||||||
private static Log logger = LogFactory.getLog(DataSourceAutoConfiguration.class);
|
|
||||||
|
|
||||||
public static final String CONFIGURATION_PREFIX = "spring.datasource";
|
public static final String CONFIGURATION_PREFIX = "spring.datasource";
|
||||||
|
|
||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
private DataSource dataSource;
|
private DataSource dataSource;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ApplicationContext applicationContext;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private DataSourceProperties properties;
|
private DataSourceProperties properties;
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
protected void initialize() {
|
|
||||||
boolean initialize = this.properties.isInitialize();
|
|
||||||
if (this.dataSource == null || !initialize) {
|
|
||||||
logger.debug("No DataSource found so not initializing");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String schema = this.properties.getSchema();
|
|
||||||
if (schema == null) {
|
|
||||||
String platform = this.properties.getPlatform();
|
|
||||||
schema = "classpath*:schema-" + platform + ".sql,";
|
|
||||||
schema += "classpath*:schema.sql,";
|
|
||||||
schema += "classpath*:data-" + platform + ".sql,";
|
|
||||||
schema += "classpath*:data.sql";
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Resource> resources = getSchemaResources(schema);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Resource> getSchemaResources(String schema) {
|
|
||||||
List<Resource> resources = new ArrayList<Resource>();
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if the {@code dataSource} being used by Spring was created from
|
* Determines if the {@code dataSource} being used by Spring was created from
|
||||||
* {@link EmbeddedDataSourceConfiguration}.
|
* {@link EmbeddedDataSourceConfiguration}.
|
||||||
|
|
|
@ -0,0 +1,181 @@
|
||||||
|
/*
|
||||||
|
* 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.context.event.ContextRefreshedEvent;
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@EnableConfigurationProperties(DataSourceProperties.class)
|
||||||
|
public class DataSourceInitialization implements
|
||||||
|
ApplicationListener<ContextRefreshedEvent> {
|
||||||
|
|
||||||
|
private static Log logger = LogFactory.getLog(DataSourceAutoConfiguration.class);
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private DataSource dataSource;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DataSourceProperties properties;
|
||||||
|
|
||||||
|
private boolean initialized = false;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ApplicationListener<DataSourceInitializedEvent> dataSourceInitializedListener() {
|
||||||
|
return new DataSourceInitializedListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(ContextRefreshedEvent event) {
|
||||||
|
if (this.properties.isDeferDdl()) {
|
||||||
|
boolean initialize = this.properties.isInitialize();
|
||||||
|
if (!initialize) {
|
||||||
|
logger.debug("Initialization disabled (not running DDL scripts)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
runSchemaScripts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
protected void initialize() {
|
||||||
|
if (!this.properties.isDeferDdl()) {
|
||||||
|
boolean initialize = this.properties.isInitialize();
|
||||||
|
if (!initialize) {
|
||||||
|
logger.debug("Initialization disabled (not running DDL scripts)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
runSchemaScripts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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<Resource> 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<Resource> getSchemaResources(String schema) {
|
||||||
|
List<Resource> resources = new ArrayList<Resource>();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class DataSourceInitializedEvent extends ApplicationEvent {
|
||||||
|
|
||||||
|
public DataSourceInitializedEvent(DataSource source) {
|
||||||
|
super(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DataSourceInitializedListener implements
|
||||||
|
ApplicationListener<DataSourceInitializedEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(DataSourceInitializedEvent event) {
|
||||||
|
runDataScripts();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -46,10 +46,14 @@ public class DataSourceProperties implements BeanClassLoaderAware, InitializingB
|
||||||
|
|
||||||
private boolean initialize = true;
|
private boolean initialize = true;
|
||||||
|
|
||||||
|
private boolean deferDdl = false;
|
||||||
|
|
||||||
private String platform = "all";
|
private String platform = "all";
|
||||||
|
|
||||||
private String schema;
|
private String schema;
|
||||||
|
|
||||||
|
private String data;
|
||||||
|
|
||||||
private boolean continueOnError = false;
|
private boolean continueOnError = false;
|
||||||
|
|
||||||
private String separator = ";";
|
private String separator = ";";
|
||||||
|
@ -154,6 +158,14 @@ public class DataSourceProperties implements BeanClassLoaderAware, InitializingB
|
||||||
this.initialize = initialize;
|
this.initialize = initialize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDeferDdl(boolean deferDdl) {
|
||||||
|
this.deferDdl = deferDdl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDeferDdl() {
|
||||||
|
return this.deferDdl;
|
||||||
|
}
|
||||||
|
|
||||||
public String getPlatform() {
|
public String getPlatform() {
|
||||||
return this.platform;
|
return this.platform;
|
||||||
}
|
}
|
||||||
|
@ -170,6 +182,14 @@ public class DataSourceProperties implements BeanClassLoaderAware, InitializingB
|
||||||
this.schema = schema;
|
this.schema = schema;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getData() {
|
||||||
|
return this.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(String script) {
|
||||||
|
this.data = script;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isContinueOnError() {
|
public boolean isContinueOnError() {
|
||||||
return this.continueOnError;
|
return this.continueOnError;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
|
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceInitialization.DataSourceInitializedEvent;
|
||||||
import org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryBuilder.EntityManagerFactoryBeanCallback;
|
import org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryBuilder.EntityManagerFactoryBeanCallback;
|
||||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration.HibernateEntityManagerCondition;
|
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration.HibernateEntityManagerCondition;
|
||||||
import org.springframework.context.ApplicationListener;
|
import org.springframework.context.ApplicationListener;
|
||||||
|
@ -90,7 +91,7 @@ public class HibernateJpaAutoConfiguration extends JpaBaseConfiguration {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class DeferredSchemaAction implements
|
private class DeferredSchemaAction implements
|
||||||
ApplicationListener<ContextRefreshedEvent> {
|
ApplicationListener<ContextRefreshedEvent> {
|
||||||
|
|
||||||
private Map<String, String> map;
|
private Map<String, String> map;
|
||||||
|
@ -105,11 +106,14 @@ public class HibernateJpaAutoConfiguration extends JpaBaseConfiguration {
|
||||||
@Override
|
@Override
|
||||||
public void onApplicationEvent(ContextRefreshedEvent event) {
|
public void onApplicationEvent(ContextRefreshedEvent event) {
|
||||||
String ddlAuto = this.map.get("hibernate.hbm2ddl.auto");
|
String ddlAuto = this.map.get("hibernate.hbm2ddl.auto");
|
||||||
if (ddlAuto == null || "none".equals(ddlAuto)) {
|
if (ddlAuto == null || "none".equals(ddlAuto) || "".equals(ddlAuto)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Bootstrap.getEntityManagerFactoryBuilder(
|
Bootstrap.getEntityManagerFactoryBuilder(
|
||||||
this.factory.getPersistenceUnitInfo(), this.map).generateSchema();
|
this.factory.getPersistenceUnitInfo(), this.map).generateSchema();
|
||||||
|
HibernateJpaAutoConfiguration.this.applicationContext
|
||||||
|
.publishEvent(new DataSourceInitializedEvent(
|
||||||
|
HibernateJpaAutoConfiguration.this.dataSource));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.springframework.beans.factory.BeanCreationException;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
|
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
|
||||||
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceInitialization;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.orm.jpa.test.City;
|
import org.springframework.boot.autoconfigure.orm.jpa.test.City;
|
||||||
|
@ -152,6 +153,8 @@ public abstract class AbstractJpaAutoConfigurationTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void usesManuallyDefinedEntityManagerFactoryBeanIfAvailable() {
|
public void usesManuallyDefinedEntityManagerFactoryBeanIfAvailable() {
|
||||||
|
EnvironmentTestUtils.addEnvironment(this.context,
|
||||||
|
"spring.datasource.initialize:false");
|
||||||
setupTestConfiguration(TestConfigurationWithEntityManagerFactory.class);
|
setupTestConfiguration(TestConfigurationWithEntityManagerFactory.class);
|
||||||
this.context.refresh();
|
this.context.refresh();
|
||||||
LocalContainerEntityManagerFactoryBean factoryBean = this.context
|
LocalContainerEntityManagerFactoryBean factoryBean = this.context
|
||||||
|
@ -188,6 +191,7 @@ public abstract class AbstractJpaAutoConfigurationTests {
|
||||||
|
|
||||||
protected void setupTestConfiguration(Class<?> configClass) {
|
protected void setupTestConfiguration(Class<?> configClass) {
|
||||||
this.context.register(configClass, EmbeddedDataSourceConfiguration.class,
|
this.context.register(configClass, EmbeddedDataSourceConfiguration.class,
|
||||||
|
DataSourceInitialization.class,
|
||||||
PropertyPlaceholderAutoConfiguration.class, getAutoConfigureClass());
|
PropertyPlaceholderAutoConfiguration.class, getAutoConfigureClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,12 +16,16 @@
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.orm.jpa;
|
package org.springframework.boot.autoconfigure.orm.jpa;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.boot.test.EnvironmentTestUtils;
|
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||||
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.not;
|
import static org.hamcrest.Matchers.not;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,6 +42,30 @@ public class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigura
|
||||||
return HibernateJpaAutoConfiguration.class;
|
return HibernateJpaAutoConfiguration.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDataScriptWithDdlAuto() throws Exception {
|
||||||
|
EnvironmentTestUtils.addEnvironment(this.context,
|
||||||
|
"spring.datasource.data:classpath:/city.sql",
|
||||||
|
"spring.datasource.schema:classpath:/ddl.sql");
|
||||||
|
setupTestConfiguration();
|
||||||
|
this.context.refresh();
|
||||||
|
assertEquals(new Integer(1),
|
||||||
|
new JdbcTemplate(this.context.getBean(DataSource.class)).queryForObject(
|
||||||
|
"SELECT COUNT(*) from CITY", Integer.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDataScriptWithDeferredDdl() throws Exception {
|
||||||
|
EnvironmentTestUtils.addEnvironment(this.context,
|
||||||
|
"spring.datasource.data:classpath:/city.sql",
|
||||||
|
"spring.datasource.deferDdl:true");
|
||||||
|
setupTestConfiguration();
|
||||||
|
this.context.refresh();
|
||||||
|
assertEquals(new Integer(1),
|
||||||
|
new JdbcTemplate(this.context.getBean(DataSource.class)).queryForObject(
|
||||||
|
"SELECT COUNT(*) from CITY", Integer.class));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCustomNamingStrategy() throws Exception {
|
public void testCustomNamingStrategy() throws Exception {
|
||||||
EnvironmentTestUtils.addEnvironment(this.context,
|
EnvironmentTestUtils.addEnvironment(this.context,
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
INSERT INTO CITY (NAME, STATE, COUNTRY, MAP) values ('Washington', 'DC', 'US', 'Google');
|
|
@ -156,7 +156,9 @@ content into your application; rather pick only the properties that you need.
|
||||||
# DATASOURCE ({sc-spring-boot-autoconfigure}/jdbc/DataSourceAutoConfiguration.{sc-ext}[DataSourceAutoConfiguration] & {sc-spring-boot-autoconfigure}//jdbc/AbstractDataSourceConfiguration.{sc-ext}[AbstractDataSourceConfiguration])
|
# DATASOURCE ({sc-spring-boot-autoconfigure}/jdbc/DataSourceAutoConfiguration.{sc-ext}[DataSourceAutoConfiguration] & {sc-spring-boot-autoconfigure}//jdbc/AbstractDataSourceConfiguration.{sc-ext}[AbstractDataSourceConfiguration])
|
||||||
spring.datasource.name= # name of the data source
|
spring.datasource.name= # name of the data source
|
||||||
spring.datasource.initialize=true # populate using data.sql
|
spring.datasource.initialize=true # populate using data.sql
|
||||||
spring.datasource.schema= # a schema resource reference
|
spring.datasource.deferDdl= # flag to indicate that schema scripts will run after the application starts (default false)
|
||||||
|
spring.datasource.schema= # a schema (DDL) script resource reference
|
||||||
|
spring.datasource.data= # a data (DML) script resource reference
|
||||||
spring.datasource.platform= # the platform to use in the schema resource (schema-${platform}.sql)
|
spring.datasource.platform= # the platform to use in the schema resource (schema-${platform}.sql)
|
||||||
spring.datasource.continueOnError=false # continue even if can't be initialized
|
spring.datasource.continueOnError=false # continue even if can't be initialized
|
||||||
spring.datasource.separator=; # statement separator in SQL initialization scripts
|
spring.datasource.separator=; # statement separator in SQL initialization scripts
|
||||||
|
|
|
@ -1165,7 +1165,7 @@ and `data-${platform}.sql` files (if present), where
|
||||||
it to the vendor name of the database (`hsqldb`, `h2`, `oracle`, `mysql`,
|
it to the vendor name of the database (`hsqldb`, `h2`, `oracle`, `mysql`,
|
||||||
`postgresql` etc.). Spring Boot enables the failfast feature of the Spring JDBC
|
`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
|
initializer by default, so if the scripts cause exceptions the application will fail
|
||||||
to start.
|
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
|
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
|
useful once an application has matured and been deployed a few times, since the scripts
|
||||||
|
|
Loading…
Reference in New Issue