Attempt to detect ddl-auto mode only if necessary
This commit defers the resolution of the default ddl auto mode only when it is absolutely necessary. This prevents Spring Boot to attempt to get a connection when it isn't necessary Closes gh-12374
This commit is contained in:
parent
317b51f2ad
commit
0207b816d9
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2018 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.
|
||||
|
|
@ -17,6 +17,7 @@
|
|||
package org.springframework.boot.autoconfigure.orm.jpa;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.sql.DataSource;
|
||||
|
|
@ -90,8 +91,9 @@ class DataSourceInitializedPublisher implements BeanPostProcessor {
|
|||
if (this.properties == null) {
|
||||
return true; // better safe than sorry
|
||||
}
|
||||
String defaultDdlAuto = (EmbeddedDatabaseConnection.isEmbedded(dataSource)
|
||||
? "create-drop" : "none");
|
||||
Supplier<String> defaultDdlAuto = () ->
|
||||
EmbeddedDatabaseConnection.isEmbedded(dataSource) ? "create-drop"
|
||||
: "none";
|
||||
Map<String, Object> hibernate = this.properties
|
||||
.getHibernateProperties(new HibernateSettings().ddlAuto(defaultDdlAuto));
|
||||
if (hibernate.containsKey("hibernate.hbm2ddl.auto")) {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import java.util.Collections;
|
|||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
|
|
@ -116,7 +117,7 @@ class HibernateJpaConfiguration extends JpaBaseConfiguration {
|
|||
|
||||
@Override
|
||||
protected Map<String, Object> getVendorProperties() {
|
||||
String defaultDdlMode = this.defaultDdlAutoProvider
|
||||
Supplier<String> defaultDdlMode = () -> this.defaultDdlAutoProvider
|
||||
.getDefaultDdlAuto(getDataSource());
|
||||
return new LinkedHashMap<>(getProperties()
|
||||
.getHibernateProperties(new HibernateSettings().ddlAuto(defaultDdlMode)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.orm.jpa;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.hibernate.boot.model.naming.ImplicitNamingStrategy;
|
||||
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
|
||||
|
|
@ -30,7 +31,7 @@ import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
|
|||
*/
|
||||
public class HibernateSettings {
|
||||
|
||||
private String ddlAuto;
|
||||
private Supplier<String> ddlAuto;
|
||||
|
||||
private ImplicitNamingStrategy implicitNamingStrategy;
|
||||
|
||||
|
|
@ -38,13 +39,25 @@ public class HibernateSettings {
|
|||
|
||||
private Collection<HibernatePropertiesCustomizer> hibernatePropertiesCustomizers;
|
||||
|
||||
public HibernateSettings ddlAuto(String ddlAuto) {
|
||||
public HibernateSettings ddlAuto(Supplier<String> ddlAuto) {
|
||||
this.ddlAuto = ddlAuto;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the default ddl auto value to use.
|
||||
* @param ddlAuto the default ddl auto if none is provided
|
||||
* @return this instance
|
||||
* @see #ddlAuto(Supplier)
|
||||
* @deprecated as of 2.0.1 in favour of {@link #ddlAuto(Supplier)}
|
||||
*/
|
||||
@Deprecated
|
||||
public HibernateSettings ddlAuto(String ddlAuto) {
|
||||
return ddlAuto(() -> ddlAuto);
|
||||
}
|
||||
|
||||
public String getDdlAuto() {
|
||||
return this.ddlAuto;
|
||||
return (this.ddlAuto != null ? this.ddlAuto.get() : null);
|
||||
}
|
||||
|
||||
public HibernateSettings implicitNamingStrategy(
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Provider;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.hibernate.boot.model.naming.ImplicitNamingStrategy;
|
||||
|
|
@ -217,7 +218,7 @@ public class JpaProperties {
|
|||
getNaming().applyNamingStrategies(result,
|
||||
settings.getImplicitNamingStrategy(),
|
||||
settings.getPhysicalNamingStrategy());
|
||||
String ddlAuto = determineDdlAuto(existing, settings.getDdlAuto());
|
||||
String ddlAuto = determineDdlAuto(existing, settings::getDdlAuto);
|
||||
if (StringUtils.hasText(ddlAuto) && !"none".equals(ddlAuto)) {
|
||||
result.put("hibernate.hbm2ddl.auto", ddlAuto);
|
||||
}
|
||||
|
|
@ -243,11 +244,13 @@ public class JpaProperties {
|
|||
}
|
||||
|
||||
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;
|
||||
Provider<String> defaultDdlAuto) {
|
||||
if (!existing.containsKey("hibernate.hbm2ddl.auto")) {
|
||||
String ddlAuto = (this.ddlAuto != null ? this.ddlAuto
|
||||
: defaultDdlAuto.get());
|
||||
if (!"none".equals(ddlAuto)) {
|
||||
return ddlAuto;
|
||||
}
|
||||
}
|
||||
if (existing.containsKey("hibernate.hbm2ddl.auto")) {
|
||||
return existing.get("hibernate.hbm2ddl.auto");
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ public class CustomHibernateJpaAutoConfigurationTests {
|
|||
.run((context) -> {
|
||||
JpaProperties bean = context.getBean(JpaProperties.class);
|
||||
Map<String, Object> hibernateProperties = bean.getHibernateProperties(
|
||||
new HibernateSettings().ddlAuto("create-drop"));
|
||||
new HibernateSettings());
|
||||
assertThat(hibernateProperties.get("hibernate.ejb.naming_strategy"))
|
||||
.isNull();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import java.sql.SQLException;
|
|||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
|
|
@ -60,7 +61,7 @@ public class JpaPropertiesTests {
|
|||
public void noCustomNamingStrategy() {
|
||||
this.contextRunner.run(assertJpaProperties((properties) -> {
|
||||
Map<String, Object> hibernateProperties = properties
|
||||
.getHibernateProperties(new HibernateSettings().ddlAuto("none"));
|
||||
.getHibernateProperties(new HibernateSettings());
|
||||
assertThat(hibernateProperties)
|
||||
.doesNotContainKeys("hibernate.ejb.naming_strategy");
|
||||
assertThat(hibernateProperties).containsEntry(
|
||||
|
|
@ -80,7 +81,7 @@ public class JpaPropertiesTests {
|
|||
.run(assertJpaProperties((properties) -> {
|
||||
Map<String, Object> hibernateProperties = properties
|
||||
.getHibernateProperties(
|
||||
new HibernateSettings().ddlAuto("none"));
|
||||
new HibernateSettings());
|
||||
assertThat(hibernateProperties).contains(
|
||||
entry("hibernate.implicit_naming_strategy",
|
||||
"com.example.Implicit"),
|
||||
|
|
@ -97,7 +98,7 @@ public class JpaPropertiesTests {
|
|||
ImplicitNamingStrategy implicitStrategy = mock(ImplicitNamingStrategy.class);
|
||||
PhysicalNamingStrategy physicalStrategy = mock(PhysicalNamingStrategy.class);
|
||||
Map<String, Object> hibernateProperties = properties
|
||||
.getHibernateProperties(new HibernateSettings().ddlAuto("none")
|
||||
.getHibernateProperties(new HibernateSettings()
|
||||
.implicitNamingStrategy(implicitStrategy)
|
||||
.physicalNamingStrategy(physicalStrategy));
|
||||
assertThat(hibernateProperties).contains(
|
||||
|
|
@ -120,7 +121,7 @@ public class JpaPropertiesTests {
|
|||
PhysicalNamingStrategy.class);
|
||||
Map<String, Object> hibernateProperties = properties
|
||||
.getHibernateProperties(
|
||||
new HibernateSettings().ddlAuto("none")
|
||||
new HibernateSettings()
|
||||
.implicitNamingStrategy(implicitStrategy)
|
||||
.physicalNamingStrategy(physicalStrategy));
|
||||
assertThat(hibernateProperties).contains(
|
||||
|
|
@ -154,7 +155,7 @@ public class JpaPropertiesTests {
|
|||
};
|
||||
Map<String, Object> hibernateProperties = properties
|
||||
.getHibernateProperties(
|
||||
new HibernateSettings().ddlAuto("none")
|
||||
new HibernateSettings()
|
||||
.implicitNamingStrategy(implicitStrategy)
|
||||
.physicalNamingStrategy(physicalStrategy)
|
||||
.hibernatePropertiesCustomizers(
|
||||
|
|
@ -177,7 +178,7 @@ public class JpaPropertiesTests {
|
|||
.run(assertJpaProperties((properties) -> {
|
||||
Map<String, Object> hibernateProperties = properties
|
||||
.getHibernateProperties(
|
||||
new HibernateSettings().ddlAuto("none"));
|
||||
new HibernateSettings());
|
||||
// You can override them as we don't provide any default
|
||||
assertThat(hibernateProperties).contains(
|
||||
entry("hibernate.implicit_naming_strategy",
|
||||
|
|
@ -193,7 +194,7 @@ public class JpaPropertiesTests {
|
|||
public void useNewIdGeneratorMappingsDefault() {
|
||||
this.contextRunner.run(assertJpaProperties((properties) -> {
|
||||
Map<String, Object> hibernateProperties = properties
|
||||
.getHibernateProperties(new HibernateSettings().ddlAuto("none"));
|
||||
.getHibernateProperties(new HibernateSettings());
|
||||
assertThat(hibernateProperties).containsEntry(
|
||||
AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, "true");
|
||||
}));
|
||||
|
|
@ -207,7 +208,7 @@ public class JpaPropertiesTests {
|
|||
.run(assertJpaProperties((properties) -> {
|
||||
Map<String, Object> hibernateProperties = properties
|
||||
.getHibernateProperties(
|
||||
new HibernateSettings().ddlAuto("none"));
|
||||
new HibernateSettings());
|
||||
assertThat(hibernateProperties).containsEntry(
|
||||
AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, "false");
|
||||
}));
|
||||
|
|
@ -248,6 +249,33 @@ public class JpaPropertiesTests {
|
|||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultDdlAutoIsNotInvokedIfPropertyIsSet() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.jpa.hibernate.ddl-auto=validate")
|
||||
.run(assertDefaultDdlAutoNotInvoked("validate"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultDdlAutoIsNotInvokedIfHibernateSpecificPropertyIsSet() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.jpa.properties.hibernate.hbm2ddl.auto=create")
|
||||
.run(assertDefaultDdlAutoNotInvoked("create"));
|
||||
}
|
||||
|
||||
private ContextConsumer<AssertableApplicationContext> assertDefaultDdlAutoNotInvoked(
|
||||
String expectedDdlAuto) {
|
||||
return assertJpaProperties((properties) -> {
|
||||
Supplier<String> ddlAutoSupplier = mock(Supplier.class);
|
||||
Map<String, Object> hibernateProperties = properties
|
||||
.getHibernateProperties(new HibernateSettings()
|
||||
.ddlAuto(ddlAutoSupplier));
|
||||
assertThat(hibernateProperties).containsEntry(
|
||||
"hibernate.hbm2ddl.auto", expectedDdlAuto);
|
||||
verify(ddlAutoSupplier, never()).get();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void determineDatabaseWithUnknownUrl() {
|
||||
this.contextRunner.run(assertJpaProperties((properties) -> {
|
||||
|
|
|
|||
Loading…
Reference in New Issue