Default Hibernate DDL auto to none with Flyway/Liquibase

This commit adds a strategy interface to specific if a given DataSource
has its schema managed. The Hibernate auto-configuration uses it to set
it to "none" if a mechanism to initialize the DataSource is
found and "create-drop" otherwise.

Both Flyway and Liquibase implements that strategy interface and
register it in the context accordingly.

Closes gh-9262
This commit is contained in:
Stephane Nicoll 2017-08-21 17:48:42 +02:00
parent 8babd5d4c5
commit afda0ec129
18 changed files with 427 additions and 78 deletions

View File

@ -80,6 +80,13 @@ public class FlywayAutoConfiguration {
return new StringOrNumberToMigrationVersionConverter();
}
@Bean
public FlywaySchemaManagementProvider flywayDefaultDdlModeProvider(
ObjectProvider<List<Flyway>> flyways) {
return new FlywaySchemaManagementProvider(
flyways.getIfAvailable(Collections::emptyList));
}
@Configuration
@ConditionalOnMissingBean(Flyway.class)
@EnableConfigurationProperties(FlywayProperties.class)

View File

@ -0,0 +1,52 @@
/*
* 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.
* 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.flyway;
import java.util.List;
import javax.sql.DataSource;
import org.flywaydb.core.Flyway;
import org.springframework.boot.jdbc.SchemaManagement;
import org.springframework.boot.jdbc.SchemaManagementProvider;
/**
* A Flyway {@link SchemaManagementProvider} that determines if the schema is managed by
* looking at available {@link Flyway} instances.
*
* @author Stephane Nicoll
*/
class FlywaySchemaManagementProvider implements SchemaManagementProvider {
private final List<Flyway> flyways;
FlywaySchemaManagementProvider(List<Flyway> flyways) {
this.flyways = flyways;
}
@Override
public SchemaManagement getSchemaManagement(DataSource dataSource) {
for (Flyway flyway : this.flyways) {
if (dataSource.equals(flyway.getDataSource())) {
return SchemaManagement.MANAGED;
}
}
return SchemaManagement.UNMANAGED;
}
}

View File

@ -17,6 +17,8 @@
package org.springframework.boot.autoconfigure.liquibase;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.persistence.EntityManagerFactory;
@ -65,6 +67,13 @@ import org.springframework.util.ReflectionUtils;
HibernateJpaAutoConfiguration.class })
public class LiquibaseAutoConfiguration {
@Bean
public LiquibaseSchemaManagementProvider liquibaseDefaultDdlModeProvider(
ObjectProvider<List<SpringLiquibase>> liquibases) {
return new LiquibaseSchemaManagementProvider(
liquibases.getIfAvailable(Collections::emptyList));
}
@Configuration
@ConditionalOnMissingBean(SpringLiquibase.class)
@EnableConfigurationProperties(LiquibaseProperties.class)

View File

@ -0,0 +1,52 @@
/*
* 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.
* 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.liquibase;
import java.util.List;
import javax.sql.DataSource;
import liquibase.integration.spring.SpringLiquibase;
import org.springframework.boot.jdbc.SchemaManagement;
import org.springframework.boot.jdbc.SchemaManagementProvider;
/**
* A Liquibase {@link SchemaManagementProvider} that determines if the schema is managed
* by looking at available {@link SpringLiquibase} instances.
*
* @author Stephane Nicoll
*/
class LiquibaseSchemaManagementProvider implements SchemaManagementProvider {
private final List<SpringLiquibase> liquibases;
LiquibaseSchemaManagementProvider(List<SpringLiquibase> liquibases) {
this.liquibases = liquibases;
}
@Override
public SchemaManagement getSchemaManagement(DataSource dataSource) {
for (SpringLiquibase liquibase : this.liquibases) {
if (dataSource.equals(liquibase.getDataSource())) {
return SchemaManagement.MANAGED;
}
}
return SchemaManagement.UNMANAGED;
}
}

View File

@ -28,6 +28,7 @@ import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.boot.autoconfigure.jdbc.DataSourceInitializedEvent;
import org.springframework.boot.jdbc.EmbeddedDatabaseConnection;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
@ -89,8 +90,10 @@ class DataSourceInitializedPublisher implements BeanPostProcessor {
if (this.properties == null) {
return true; // better safe than sorry
}
Map<String, String> hibernate = this.properties
.getHibernateProperties(dataSource);
String defaultDdlAuto = (EmbeddedDatabaseConnection.isEmbedded(dataSource)
? "create-drop" : "none");
Map<String, String> hibernate = this.properties.getHibernateProperties(
defaultDdlAuto);
if (hibernate.containsKey("hibernate.hbm2ddl.auto")) {
return true;
}

View File

@ -0,0 +1,64 @@
/*
* 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.
* 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.orm.jpa;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.boot.jdbc.EmbeddedDatabaseConnection;
import org.springframework.boot.jdbc.SchemaManagement;
import org.springframework.boot.jdbc.SchemaManagementProvider;
/**
* A {@link SchemaManagementProvider} that invokes a configurable number of
* {@link SchemaManagementProvider} instances for embedded data sources only.
*
* @author Stephane Nicoll
*/
class HibernateDefaultDdlAutoProvider implements SchemaManagementProvider {
private final List<SchemaManagementProvider> providers;
HibernateDefaultDdlAutoProvider(List<SchemaManagementProvider> providers) {
this.providers = providers;
}
public String getDefaultDdlAuto(DataSource dataSource) {
if (!EmbeddedDatabaseConnection.isEmbedded(dataSource)) {
return "none";
}
SchemaManagement schemaManagement = getSchemaManagement(dataSource);
if (SchemaManagement.MANAGED.equals(schemaManagement)) {
return "none";
}
return "create-drop";
}
@Override
public SchemaManagement getSchemaManagement(DataSource dataSource) {
for (SchemaManagementProvider provider : this.providers) {
SchemaManagement schemaManagement = provider.getSchemaManagement(dataSource);
if (SchemaManagement.MANAGED.equals(schemaManagement)) {
return schemaManagement;
}
}
return SchemaManagement.UNMANAGED;
}
}

View File

@ -17,7 +17,9 @@
package org.springframework.boot.autoconfigure.orm.jpa;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
@ -37,6 +39,7 @@ import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration.HibernateEntityManagerCondition;
import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers;
import org.springframework.boot.jdbc.SchemaManagementProvider;
import org.springframework.boot.orm.jpa.hibernate.SpringJtaPlatform;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.Conditional;
@ -85,12 +88,17 @@ public class HibernateJpaAutoConfiguration extends JpaBaseConfiguration {
"org.hibernate.engine.transaction.jta.platform.internal.WebSphereExtendedJtaPlatform",
"org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform", };
private final HibernateDefaultDdlAutoProvider defaultDdlAutoProvider;
public HibernateJpaAutoConfiguration(DataSource dataSource,
JpaProperties jpaProperties,
ObjectProvider<JtaTransactionManager> jtaTransactionManager,
ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers,
ObjectProvider<List<SchemaManagementProvider>> providers) {
super(dataSource, jpaProperties, jtaTransactionManager,
transactionManagerCustomizers);
this.defaultDdlAutoProvider = new HibernateDefaultDdlAutoProvider(
providers.getIfAvailable(Collections::emptyList));
}
@Override
@ -101,7 +109,9 @@ public class HibernateJpaAutoConfiguration extends JpaBaseConfiguration {
@Override
protected Map<String, Object> getVendorProperties() {
Map<String, Object> vendorProperties = new LinkedHashMap<>();
vendorProperties.putAll(getProperties().getHibernateProperties(getDataSource()));
String defaultDdlMode = this.defaultDdlAutoProvider.getDefaultDdlAuto(
getDataSource());
vendorProperties.putAll(getProperties().getHibernateProperties(defaultDdlMode));
return vendorProperties;
}

View File

@ -22,7 +22,6 @@ import java.util.Map;
import javax.sql.DataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.EmbeddedDatabaseConnection;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.util.StringUtils;
@ -119,11 +118,11 @@ public class JpaProperties {
/**
* Get configuration properties for the initialization of the main Hibernate
* EntityManagerFactory.
* @param dataSource the DataSource in case it is needed to determine the properties
* @param defaultDdlAuto the default DDL auto (can be {@code null})
* @return some Hibernate properties for configuration
*/
public Map<String, String> getHibernateProperties(DataSource dataSource) {
return this.hibernate.getAdditionalProperties(this.properties, dataSource);
public Map<String, String> getHibernateProperties(String defaultDdlAuto) {
return this.hibernate.getAdditionalProperties(this.properties, defaultDdlAuto);
}
/**
@ -146,8 +145,8 @@ public class JpaProperties {
/**
* DDL mode. This is actually a shortcut for the "hibernate.hbm2ddl.auto"
* property. Default to "create-drop" when using an embedded database, "none"
* otherwise.
* property. Default to "create-drop" when using an embedded database and no
* schema manager was detected, "none" otherwise.
*/
private String ddlAuto;
@ -181,11 +180,11 @@ public class JpaProperties {
}
private Map<String, String> getAdditionalProperties(Map<String, String> existing,
DataSource dataSource) {
String defaultDdlAuto) {
Map<String, String> result = new HashMap<>(existing);
applyNewIdGeneratorMappings(result);
getNaming().applyNamingStrategies(result);
String ddlAuto = getOrDeduceDdlAuto(existing, dataSource);
String ddlAuto = determineDdlAuto(existing, defaultDdlAuto);
if (StringUtils.hasText(ddlAuto) && !"none".equals(ddlAuto)) {
result.put("hibernate.hbm2ddl.auto", ddlAuto);
}
@ -205,10 +204,9 @@ public class JpaProperties {
}
}
private String getOrDeduceDdlAuto(Map<String, String> existing,
DataSource dataSource) {
String ddlAuto = (this.ddlAuto != null ? this.ddlAuto
: getDefaultDdlAuto(dataSource));
private String determineDdlAuto(Map<String, String> existing,
String defaultDdlAuto) {
String ddlAuto = (this.ddlAuto != null ? this.ddlAuto : defaultDdlAuto);
if (!existing.containsKey("hibernate." + "hbm2ddl.auto")
&& !"none".equals(ddlAuto)) {
return ddlAuto;
@ -219,13 +217,6 @@ public class JpaProperties {
return "none";
}
private String getDefaultDdlAuto(DataSource dataSource) {
if (EmbeddedDatabaseConnection.isEmbedded(dataSource)) {
return "create-drop";
}
return "none";
}
}
public static class Naming {

View File

@ -40,6 +40,7 @@ import org.springframework.beans.factory.BeanCreationException;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
import org.springframework.boot.jdbc.SchemaManagement;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@ -114,6 +115,19 @@ public class FlywayAutoConfigurationTests {
.isEqualTo(this.context.getBean("flywayDataSource"));
}
@Test
public void schemaManagementProviderDetectsDataSource() throws Exception {
registerAndRefresh(FlywayDataSourceConfiguration.class,
EmbeddedDataSourceConfiguration.class, FlywayAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
FlywaySchemaManagementProvider schemaManagementProvider = this.context.getBean(
FlywaySchemaManagementProvider.class);
assertThat(schemaManagementProvider.getSchemaManagement(this.context.getBean(
DataSource.class))).isEqualTo(SchemaManagement.UNMANAGED);
assertThat(schemaManagementProvider.getSchemaManagement(this.context.getBean(
"flywayDataSource", DataSource.class))).isEqualTo(SchemaManagement.MANAGED);
}
@Test
public void defaultFlyway() throws Exception {
registerAndRefresh(EmbeddedDataSourceConfiguration.class,

View File

@ -59,44 +59,6 @@ public class CustomHibernateJpaAutoConfigurationTests {
this.context.close();
}
@Test
public void testDefaultDdlAutoForMySql() throws Exception {
// Set up environment so we get a MySQL database but don't require server to be
// running...
TestPropertyValues
.of("spring.datasource.type:"
+ org.apache.tomcat.jdbc.pool.DataSource.class.getName(),
"spring.datasource.database:mysql",
"spring.datasource.url:jdbc:mysql://localhost/nonexistent",
"spring.datasource.initialize:false", "spring.jpa.database:MYSQL")
.applyTo(this.context);
this.context.register(TestConfiguration.class, DataSourceAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class,
HibernateJpaAutoConfiguration.class);
this.context.refresh();
JpaProperties bean = this.context.getBean(JpaProperties.class);
DataSource dataSource = this.context.getBean(DataSource.class);
String actual = bean.getHibernateProperties(dataSource)
.get("hibernate.hbm2ddl.auto");
// Default is generic and safe
assertThat(actual).isNull();
}
@Test
public void testDefaultDdlAutoForEmbedded() throws Exception {
TestPropertyValues.of("spring.datasource.initialize:false").applyTo(this.context);
this.context.register(TestConfiguration.class,
EmbeddedDataSourceConfiguration.class,
PropertyPlaceholderAutoConfiguration.class,
HibernateJpaAutoConfiguration.class);
this.context.refresh();
JpaProperties bean = this.context.getBean(JpaProperties.class);
DataSource dataSource = this.context.getBean(DataSource.class);
String actual = bean.getHibernateProperties(dataSource)
.get("hibernate.hbm2ddl.auto");
assertThat(actual).isEqualTo("create-drop");
}
@Test
public void testNamingStrategyDelegatorTakesPrecedence() {
TestPropertyValues
@ -108,8 +70,7 @@ public class CustomHibernateJpaAutoConfigurationTests {
HibernateJpaAutoConfiguration.class);
this.context.refresh();
JpaProperties bean = this.context.getBean(JpaProperties.class);
DataSource dataSource = this.context.getBean(DataSource.class);
Map<String, String> hibernateProperties = bean.getHibernateProperties(dataSource);
Map<String, String> hibernateProperties = bean.getHibernateProperties("create-drop");
assertThat(hibernateProperties.get("hibernate.ejb.naming_strategy")).isNull();
}

View File

@ -0,0 +1,104 @@
/*
* 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.
* 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.orm.jpa;
import java.util.Collections;
import javax.sql.DataSource;
import org.junit.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.jdbc.SchemaManagement;
import org.springframework.boot.jdbc.SchemaManagementProvider;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link HibernateDefaultDdlAutoProvider}.
*
* @author Stephane Nicoll
*/
public class HibernateDefaultDdlAutoProviderTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class))
.withPropertyValues("spring.datasource.initialize:false");
@Test
public void defaultDdlAutoForMysql() {
// Set up environment so we get a MySQL database but don't require server to be
// running...
this.contextRunner.withPropertyValues(
"spring.datasource.type:"
+ org.apache.tomcat.jdbc.pool.DataSource.class.getName(),
"spring.datasource.database:mysql",
"spring.datasource.url:jdbc:mysql://localhost/nonexistent",
"spring.jpa.database:MYSQL"
).run((context) -> {
HibernateDefaultDdlAutoProvider ddlAutoProvider = new HibernateDefaultDdlAutoProvider(
Collections.emptyList());
assertThat(ddlAutoProvider.getDefaultDdlAuto(
context.getBean(DataSource.class))).isEqualTo("none");
});
}
@Test
public void defaultDDlAutoForEmbedded() {
this.contextRunner.run((context) -> {
HibernateDefaultDdlAutoProvider ddlAutoProvider = new HibernateDefaultDdlAutoProvider(
Collections.emptyList());
assertThat(ddlAutoProvider.getDefaultDdlAuto(
context.getBean(DataSource.class))).isEqualTo("create-drop");
});
}
@Test
public void defaultDDlAutoForEmbeddedWithPositiveContributor() {
this.contextRunner.run((context) -> {
DataSource dataSource = context.getBean(DataSource.class);
SchemaManagementProvider provider = mock(SchemaManagementProvider.class);
given(provider.getSchemaManagement(dataSource))
.willReturn(SchemaManagement.MANAGED);
HibernateDefaultDdlAutoProvider ddlAutoProvider = new HibernateDefaultDdlAutoProvider(
Collections.singletonList(provider));
assertThat(ddlAutoProvider.getDefaultDdlAuto(
dataSource)).isEqualTo("none");
});
}
@Test
public void defaultDDlAutoForEmbeddedWithNegativeContributor() {
this.contextRunner.run((context) -> {
DataSource dataSource = context.getBean(DataSource.class);
SchemaManagementProvider provider = mock(SchemaManagementProvider.class);
given(provider.getSchemaManagement(dataSource))
.willReturn(SchemaManagement.UNMANAGED);
HibernateDefaultDdlAutoProvider ddlAutoProvider = new HibernateDefaultDdlAutoProvider(
Collections.singletonList(provider));
assertThat(ddlAutoProvider.getDefaultDdlAuto(
dataSource)).isEqualTo("create-drop");
});
}
}

View File

@ -101,6 +101,13 @@ public class HibernateJpaAutoConfigurationTests
.isTrue();
}
@Test
public void testFlywaySwitchOffDdlAuto() throws Exception {
load(new Class<?>[0], new Class<?>[] { FlywayAutoConfiguration.class },
"spring.datasource.initialize:false",
"spring.flyway.locations:classpath:db/city");
}
@Test
public void testFlywayPlusValidation() throws Exception {
load(new Class<?>[0], new Class<?>[] { FlywayAutoConfiguration.class },

View File

@ -62,7 +62,7 @@ public class JpaPropertiesTests {
public void noCustomNamingStrategy() throws Exception {
JpaProperties properties = load();
Map<String, String> hibernateProperties = properties
.getHibernateProperties(mockStandaloneDataSource());
.getHibernateProperties("none");
assertThat(hibernateProperties)
.doesNotContainKeys("hibernate.ejb.naming_strategy");
assertThat(hibernateProperties).containsEntry(
@ -79,7 +79,7 @@ public class JpaPropertiesTests {
"spring.jpa.hibernate.naming.implicit-strategy:com.example.Implicit",
"spring.jpa.hibernate.naming.physical-strategy:com.example.Physical");
Map<String, String> hibernateProperties = properties
.getHibernateProperties(mockStandaloneDataSource());
.getHibernateProperties("none");
assertThat(hibernateProperties).contains(
entry("hibernate.implicit_naming_strategy", "com.example.Implicit"),
entry("hibernate.physical_naming_strategy", "com.example.Physical"));
@ -93,7 +93,7 @@ public class JpaPropertiesTests {
"spring.jpa.properties.hibernate.implicit_naming_strategy:com.example.Implicit",
"spring.jpa.properties.hibernate.physical_naming_strategy:com.example.Physical");
Map<String, String> hibernateProperties = properties
.getHibernateProperties(mockStandaloneDataSource());
.getHibernateProperties("none");
// You can override them as we don't provide any default
assertThat(hibernateProperties).contains(
entry("hibernate.implicit_naming_strategy", "com.example.Implicit"),
@ -106,7 +106,7 @@ public class JpaPropertiesTests {
public void useNewIdGeneratorMappingsDefault() throws Exception {
JpaProperties properties = load();
Map<String, String> hibernateProperties = properties
.getHibernateProperties(mockStandaloneDataSource());
.getHibernateProperties("none");
assertThat(hibernateProperties)
.containsEntry(AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, "true");
}
@ -116,7 +116,7 @@ public class JpaPropertiesTests {
JpaProperties properties = load(
"spring.jpa.hibernate.use-new-id-generator-mappings:false");
Map<String, String> hibernateProperties = properties
.getHibernateProperties(mockStandaloneDataSource());
.getHibernateProperties("none");
assertThat(hibernateProperties)
.containsEntry(AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, "false");
}

View File

@ -740,7 +740,7 @@ content into your application; rather pick only the properties that you need.
spring.jpa.database= # Target database to operate on, auto-detected by default. Can be alternatively set using the "databasePlatform" property.
spring.jpa.database-platform= # Name of the target database to operate on, auto-detected by default. Can be alternatively set using the "Database" enum.
spring.jpa.generate-ddl=false # Initialize the schema on startup.
spring.jpa.hibernate.ddl-auto= # DDL mode. This is actually a shortcut for the "hibernate.hbm2ddl.auto" property. Default to "create-drop" when using an embedded database, "none" otherwise.
spring.jpa.hibernate.ddl-auto= # DDL mode. This is actually a shortcut for the "hibernate.hbm2ddl.auto" property. Default to "create-drop" when using an embedded database and no schema manager was detected, "none" otherwise.
spring.jpa.hibernate.naming.implicit-strategy= # Hibernate 5 implicit naming strategy fully qualified name.
spring.jpa.hibernate.naming.physical-strategy= # Hibernate 5 physical naming strategy fully qualified name.
spring.jpa.hibernate.use-new-id-generator-mappings= # Use Hibernate's newer IdentifierGenerator for AUTO, TABLE and SEQUENCE.

View File

@ -1671,7 +1671,10 @@ configuration properties. Some of them are automatically detected according to t
so you shouldn't have to set them.
The `spring.jpa.hibernate.ddl-auto` is a special case in that it has different defaults
depending on whether you are using an embedded database (`create-drop`) or not (`none`).
depending on runtime conditions. If an embedded database is used and no schema manager,
such as Liquibase or Flyway, is handling the `DataSource` it then defaults to
`create-drop`. In all other cases it defaults to `none`.
The dialect to use is also automatically detected based on the current `DataSource` but
you can set `spring.jpa.database` yourself if you want to be explicit and bypass that
check on startup.
@ -1890,12 +1893,13 @@ database. This is controlled through two external properties:
=== Initialize a database using Hibernate
You can set `spring.jpa.hibernate.ddl-auto` explicitly and the standard Hibernate property
values are `none`, `validate`, `update`, `create`, `create-drop`. Spring Boot chooses a
default value for you based on whether it thinks your database is embedded (default
`create-drop`) or not (default `none`). An embedded database is detected by looking at the
`Connection` type: `hsqldb`, `h2` and `derby` are embedded, the rest are not. Be careful
when switching from in-memory to a '`real`' database that you don't make assumptions about
the existence of the tables and data in the new platform. You either have to set `ddl-auto`
explicitly, or use one of the other mechanisms to initialize the database.
default value for you based on whether it thinks your database is embedded: default to
`create-drop` if no schema manager has been detected, `none` in all other cases. An
embedded database is detected by looking at the `Connection` type: `hsqldb`, `h2` and
`derby` are embedded, the rest are not. Be careful when switching from in-memory to a
'`real`' database that you don't make assumptions about the existence of the tables and
data in the new platform. You either have to set `ddl-auto` explicitly, or use one of the
other mechanisms to initialize the database.
NOTE: You can output the schema creation by enabling the `org.hibernate.SQL` logger. This
is done for you automatically if you enable the <<boot-features-logging-console-output,debug mode>>.

View File

@ -1,5 +1,3 @@
management.security.enabled=false
spring.jpa.hibernate.ddl-auto=none
spring.h2.console.enabled=true

View File

@ -0,0 +1,37 @@
/*
* 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.
* 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.jdbc;
/**
* An enumeration of the available schema management options.
*
* @author Stephane Nicoll
* @since 2.0.0
*/
public enum SchemaManagement {
/**
* The schema is managed and will be created at the appropriate time.
*/
MANAGED,
/**
* The schema is not managed.
*/
UNMANAGED
}

View File

@ -0,0 +1,36 @@
/*
* 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.
* 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.jdbc;
import javax.sql.DataSource;
/**
* Strategy interface to determine the {@link SchemaManagement} of a {@link DataSource}.
*
* @author Stephane Nicoll
* @since 2.0.0
*/
public interface SchemaManagementProvider {
/**
* Return the {@link SchemaManagement} for the specified {@link DataSource}.
* @param dataSource the dataSource to handle
* @return the {@link SchemaManagement} for the {@link DataSource}.
*/
SchemaManagement getSchemaManagement(DataSource dataSource);
}