From ab19db19a3d05e3135a1d38cb3a3680351b5d427 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Wed, 6 Jun 2018 11:47:22 +0200 Subject: [PATCH] Move Hibernate settings to a dedicated class Closes gh-1327 --- .../jpa/DataSourceInitializedPublisher.java | 16 +- .../orm/jpa/HibernateJpaConfiguration.java | 13 +- .../orm/jpa/HibernateProperties.java | 183 ++++++++++++++++++ .../autoconfigure/orm/jpa/JpaProperties.java | 158 --------------- ...tomHibernateJpaAutoConfigurationTests.java | 12 +- .../orm/jpa/HibernatePropertiesTests.java | 167 ++++++++++++++++ .../orm/jpa/JpaPropertiesTests.java | 117 ----------- 7 files changed, 378 insertions(+), 288 deletions(-) create mode 100644 spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateProperties.java create mode 100644 spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernatePropertiesTests.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/DataSourceInitializedPublisher.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/DataSourceInitializedPublisher.java index b880a816a2..fdfc2815f8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/DataSourceInitializedPublisher.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/DataSourceInitializedPublisher.java @@ -48,7 +48,9 @@ class DataSourceInitializedPublisher implements BeanPostProcessor { private DataSource dataSource; - private JpaProperties properties; + private JpaProperties jpaProperties; + + private HibernateProperties hibernateProperties; @Override public Object postProcessBeforeInitialization(Object bean, String beanName) @@ -64,7 +66,10 @@ class DataSourceInitializedPublisher implements BeanPostProcessor { this.dataSource = (DataSource) bean; } if (bean instanceof JpaProperties) { - this.properties = (JpaProperties) bean; + this.jpaProperties = (JpaProperties) bean; + } + if (bean instanceof HibernateProperties) { + this.hibernateProperties = (HibernateProperties) bean; } if (bean instanceof EntityManagerFactory) { publishEventIfRequired((EntityManagerFactory) bean); @@ -88,13 +93,14 @@ class DataSourceInitializedPublisher implements BeanPostProcessor { } private boolean isInitializingDatabase(DataSource dataSource) { - if (this.properties == null) { + if (this.jpaProperties == null || this.hibernateProperties == null) { return true; // better safe than sorry } Supplier defaultDdlAuto = () -> (EmbeddedDatabaseConnection .isEmbedded(dataSource) ? "create-drop" : "none"); - Map hibernate = this.properties - .getHibernateProperties(new HibernateSettings().ddlAuto(defaultDdlAuto)); + Map hibernate = this.hibernateProperties + .determineHibernateProperties(this.jpaProperties.getProperties(), + new HibernateSettings().ddlAuto(defaultDdlAuto)); if (hibernate.containsKey("hibernate.hbm2ddl.auto")) { return true; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.java index 6273a39832..5141bbf609 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.java @@ -34,6 +34,7 @@ import org.hibernate.boot.model.naming.PhysicalNamingStrategy; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.jdbc.SchemaManagementProvider; import org.springframework.boot.jdbc.metadata.CompositeDataSourcePoolMetadataProvider; import org.springframework.boot.jdbc.metadata.DataSourcePoolMetadata; @@ -57,6 +58,7 @@ import org.springframework.util.ClassUtils; * @since 2.0.0 */ @Configuration +@EnableConfigurationProperties(HibernateProperties.class) @ConditionalOnSingleCandidate(DataSource.class) class HibernateJpaConfiguration extends JpaBaseConfiguration { @@ -81,6 +83,8 @@ class HibernateJpaConfiguration extends JpaBaseConfiguration { "org.hibernate.engine.transaction.jta.platform.internal.WebSphereExtendedJtaPlatform", "org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform" }; + private final HibernateProperties hibernateProperties; + private final HibernateDefaultDdlAutoProvider defaultDdlAutoProvider; private DataSourcePoolMetadataProvider poolMetadataProvider; @@ -90,6 +94,7 @@ class HibernateJpaConfiguration extends JpaBaseConfiguration { HibernateJpaConfiguration(DataSource dataSource, JpaProperties jpaProperties, ObjectProvider jtaTransactionManager, ObjectProvider transactionManagerCustomizers, + HibernateProperties hibernateProperties, ObjectProvider> metadataProviders, ObjectProvider> providers, ObjectProvider physicalNamingStrategy, @@ -97,6 +102,7 @@ class HibernateJpaConfiguration extends JpaBaseConfiguration { ObjectProvider> hibernatePropertiesCustomizers) { super(dataSource, jpaProperties, jtaTransactionManager, transactionManagerCustomizers); + this.hibernateProperties = hibernateProperties; this.defaultDdlAutoProvider = new HibernateDefaultDdlAutoProvider( providers.getIfAvailable(Collections::emptyList)); this.poolMetadataProvider = new CompositeDataSourcePoolMetadataProvider( @@ -130,9 +136,10 @@ class HibernateJpaConfiguration extends JpaBaseConfiguration { protected Map getVendorProperties() { Supplier defaultDdlMode = () -> this.defaultDdlAutoProvider .getDefaultDdlAuto(getDataSource()); - return new LinkedHashMap<>( - getProperties().getHibernateProperties(new HibernateSettings() - .ddlAuto(defaultDdlMode).hibernatePropertiesCustomizers( + return new LinkedHashMap<>(this.hibernateProperties.determineHibernateProperties( + getProperties().getProperties(), + new HibernateSettings().ddlAuto(defaultDdlMode) + .hibernatePropertiesCustomizers( this.hibernatePropertiesCustomizers))); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateProperties.java new file mode 100644 index 0000000000..25fb54a7ee --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateProperties.java @@ -0,0 +1,183 @@ +/* + * 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. + * 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.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Supplier; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.util.Assert; +import org.springframework.util.ObjectUtils; +import org.springframework.util.StringUtils; + +/** + * Configuration properties for Hibernate. + * + * @author Stephane Nicoll + * @since 2.1.0 + * @see JpaProperties + */ +@ConfigurationProperties("spring.jpa.hibernate") +public class HibernateProperties { + + private static final String USE_NEW_ID_GENERATOR_MAPPINGS = "hibernate.id." + + "new_generator_mappings"; + + private final Naming naming = new Naming(); + + /** + * DDL mode. This is actually a shortcut for the "hibernate.hbm2ddl.auto" property. + * Defaults to "create-drop" when using an embedded database and no schema manager was + * detected. Otherwise, defaults to "none". + */ + private String ddlAuto; + + /** + * Whether to use Hibernate's newer IdentifierGenerator for AUTO, TABLE and SEQUENCE. + * This is actually a shortcut for the "hibernate.id.new_generator_mappings" property. + * When not specified will default to "true". + */ + private Boolean useNewIdGeneratorMappings; + + public String getDdlAuto() { + return this.ddlAuto; + } + + public void setDdlAuto(String ddlAuto) { + this.ddlAuto = ddlAuto; + } + + public Boolean isUseNewIdGeneratorMappings() { + return this.useNewIdGeneratorMappings; + } + + public void setUseNewIdGeneratorMappings(Boolean useNewIdGeneratorMappings) { + this.useNewIdGeneratorMappings = useNewIdGeneratorMappings; + } + + public Naming getNaming() { + return this.naming; + } + + /** + * Determine the configuration properties for the initialization of the main Hibernate + * EntityManagerFactory based on standard JPA properties and + * {@link HibernateSettings}. + * @param jpaProperties standard jpa properties + * @param settings the settings to apply when determining the configuration properties + * @return the Hibernate properties to use + */ + public Map determineHibernateProperties( + Map jpaProperties, HibernateSettings settings) { + Assert.notNull(jpaProperties, "JpaProperties must not be null"); + Assert.notNull(settings, "Settings must not be null"); + return getAdditionalProperties(jpaProperties, settings); + } + + private Map getAdditionalProperties(Map existing, + HibernateSettings settings) { + Map result = new HashMap<>(existing); + applyNewIdGeneratorMappings(result); + getNaming().applyNamingStrategies(result); + String ddlAuto = determineDdlAuto(existing, settings::getDdlAuto); + if (StringUtils.hasText(ddlAuto) && !"none".equals(ddlAuto)) { + result.put("hibernate.hbm2ddl.auto", ddlAuto); + } + else { + result.remove("hibernate.hbm2ddl.auto"); + } + Collection customizers = settings + .getHibernatePropertiesCustomizers(); + if (!ObjectUtils.isEmpty(customizers)) { + customizers.forEach((customizer) -> customizer.customize(result)); + } + return result; + } + + private void applyNewIdGeneratorMappings(Map result) { + if (this.useNewIdGeneratorMappings != null) { + result.put(USE_NEW_ID_GENERATOR_MAPPINGS, + this.useNewIdGeneratorMappings.toString()); + } + else if (!result.containsKey(USE_NEW_ID_GENERATOR_MAPPINGS)) { + result.put(USE_NEW_ID_GENERATOR_MAPPINGS, "true"); + } + } + + private String determineDdlAuto(Map existing, + Supplier defaultDdlAuto) { + String ddlAuto = existing.get("hibernate.hbm2ddl.auto"); + if (ddlAuto != null) { + return ddlAuto; + } + return (this.ddlAuto != null ? this.ddlAuto : defaultDdlAuto.get()); + } + + public static class Naming { + + private static final String DEFAULT_PHYSICAL_STRATEGY = "org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy"; + + private static final String DEFAULT_IMPLICIT_STRATEGY = "org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy"; + + /** + * Fully qualified name of the implicit naming strategy. + */ + private String implicitStrategy; + + /** + * Fully qualified name of the physical naming strategy. + */ + private String physicalStrategy; + + public String getImplicitStrategy() { + return this.implicitStrategy; + } + + public void setImplicitStrategy(String implicitStrategy) { + this.implicitStrategy = implicitStrategy; + } + + public String getPhysicalStrategy() { + return this.physicalStrategy; + } + + public void setPhysicalStrategy(String physicalStrategy) { + this.physicalStrategy = physicalStrategy; + } + + private void applyNamingStrategies(Map properties) { + applyNamingStrategy(properties, "hibernate.implicit_naming_strategy", + this.implicitStrategy, DEFAULT_IMPLICIT_STRATEGY); + applyNamingStrategy(properties, "hibernate.physical_naming_strategy", + this.physicalStrategy, DEFAULT_PHYSICAL_STRATEGY); + } + + private void applyNamingStrategy(Map properties, String key, + Object strategy, Object defaultStrategy) { + if (strategy != null) { + properties.put(key, strategy); + } + else if (defaultStrategy != null && !properties.containsKey(key)) { + properties.put(key, defaultStrategy); + } + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaProperties.java index 3587f9b055..e4ece17f16 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaProperties.java @@ -17,18 +17,14 @@ package org.springframework.boot.autoconfigure.orm.jpa; import java.util.ArrayList; -import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.function.Supplier; import javax.sql.DataSource; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.orm.jpa.vendor.Database; -import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; /** * External configuration properties for a JPA EntityManagerFactory created by Spring. @@ -81,8 +77,6 @@ public class JpaProperties { */ private Boolean openInView; - private Hibernate hibernate = new Hibernate(); - public Map getProperties() { return this.properties; } @@ -135,24 +129,6 @@ public class JpaProperties { this.openInView = openInView; } - public Hibernate getHibernate() { - return this.hibernate; - } - - public void setHibernate(Hibernate hibernate) { - this.hibernate = hibernate; - } - - /** - * Get configuration properties for the initialization of the main Hibernate - * EntityManagerFactory. - * @param settings the settings to apply when determining the configuration properties - * @return some Hibernate properties for configuration - */ - public Map getHibernateProperties(HibernateSettings settings) { - return this.hibernate.getAdditionalProperties(this.properties, settings); - } - /** * Determine the {@link Database} to use based on this configuration and the primary * {@link DataSource}. @@ -166,138 +142,4 @@ public class JpaProperties { return DatabaseLookup.getDatabase(dataSource); } - public static class Hibernate { - - private static final String USE_NEW_ID_GENERATOR_MAPPINGS = "hibernate.id." - + "new_generator_mappings"; - - /** - * DDL mode. This is actually a shortcut for the "hibernate.hbm2ddl.auto" - * property. Defaults to "create-drop" when using an embedded database and no - * schema manager was detected. Otherwise, defaults to "none". - */ - private String ddlAuto; - - /** - * Whether to use Hibernate's newer IdentifierGenerator for AUTO, TABLE and - * SEQUENCE. This is actually a shortcut for the - * "hibernate.id.new_generator_mappings" property. When not specified will default - * to "true". - */ - private Boolean useNewIdGeneratorMappings; - - private final Naming naming = new Naming(); - - public String getDdlAuto() { - return this.ddlAuto; - } - - public void setDdlAuto(String ddlAuto) { - this.ddlAuto = ddlAuto; - } - - public Boolean isUseNewIdGeneratorMappings() { - return this.useNewIdGeneratorMappings; - } - - public void setUseNewIdGeneratorMappings(Boolean useNewIdGeneratorMappings) { - this.useNewIdGeneratorMappings = useNewIdGeneratorMappings; - } - - public Naming getNaming() { - return this.naming; - } - - private Map getAdditionalProperties(Map existing, - HibernateSettings settings) { - Map result = new HashMap<>(existing); - applyNewIdGeneratorMappings(result); - getNaming().applyNamingStrategies(result); - String ddlAuto = determineDdlAuto(existing, settings::getDdlAuto); - if (StringUtils.hasText(ddlAuto) && !"none".equals(ddlAuto)) { - result.put("hibernate.hbm2ddl.auto", ddlAuto); - } - else { - result.remove("hibernate.hbm2ddl.auto"); - } - Collection customizers = settings - .getHibernatePropertiesCustomizers(); - if (!ObjectUtils.isEmpty(customizers)) { - customizers.forEach((customizer) -> customizer.customize(result)); - } - return result; - } - - private void applyNewIdGeneratorMappings(Map result) { - if (this.useNewIdGeneratorMappings != null) { - result.put(USE_NEW_ID_GENERATOR_MAPPINGS, - this.useNewIdGeneratorMappings.toString()); - } - else if (!result.containsKey(USE_NEW_ID_GENERATOR_MAPPINGS)) { - result.put(USE_NEW_ID_GENERATOR_MAPPINGS, "true"); - } - } - - private String determineDdlAuto(Map existing, - Supplier defaultDdlAuto) { - String ddlAuto = existing.get("hibernate.hbm2ddl.auto"); - if (ddlAuto != null) { - return ddlAuto; - } - return (this.ddlAuto != null ? this.ddlAuto : defaultDdlAuto.get()); - } - - } - - public static class Naming { - - private static final String DEFAULT_PHYSICAL_STRATEGY = "org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy"; - - private static final String DEFAULT_IMPLICIT_STRATEGY = "org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy"; - - /** - * Fully qualified name of the implicit naming strategy. - */ - private String implicitStrategy; - - /** - * Fully qualified name of the physical naming strategy. - */ - private String physicalStrategy; - - public String getImplicitStrategy() { - return this.implicitStrategy; - } - - public void setImplicitStrategy(String implicitStrategy) { - this.implicitStrategy = implicitStrategy; - } - - public String getPhysicalStrategy() { - return this.physicalStrategy; - } - - public void setPhysicalStrategy(String physicalStrategy) { - this.physicalStrategy = physicalStrategy; - } - - private void applyNamingStrategies(Map properties) { - applyNamingStrategy(properties, "hibernate.implicit_naming_strategy", - this.implicitStrategy, DEFAULT_IMPLICIT_STRATEGY); - applyNamingStrategy(properties, "hibernate.physical_naming_strategy", - this.physicalStrategy, DEFAULT_PHYSICAL_STRATEGY); - } - - private void applyNamingStrategy(Map properties, String key, - Object strategy, Object defaultStrategy) { - if (strategy != null) { - properties.put(key, strategy); - } - else if (defaultStrategy != null && !properties.containsKey(key)) { - properties.put(key, defaultStrategy); - } - } - - } - } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/CustomHibernateJpaAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/CustomHibernateJpaAutoConfigurationTests.java index c4314c12d7..bb65355b30 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/CustomHibernateJpaAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/CustomHibernateJpaAutoConfigurationTests.java @@ -67,11 +67,13 @@ public class CustomHibernateJpaAutoConfigurationTests { "spring.jpa.properties.hibernate.ejb.naming_strategy_delegator:" + "org.hibernate.cfg.naming.ImprovedNamingStrategyDelegator") .run((context) -> { - JpaProperties bean = context.getBean(JpaProperties.class); - Map hibernateProperties = bean - .getHibernateProperties(new HibernateSettings()); - assertThat(hibernateProperties.get("hibernate.ejb.naming_strategy")) - .isNull(); + JpaProperties jpaProperties = context.getBean(JpaProperties.class); + HibernateProperties hibernateProperties = context + .getBean(HibernateProperties.class); + Map properties = hibernateProperties + .determineHibernateProperties(jpaProperties.getProperties(), + new HibernateSettings()); + assertThat(properties.get("hibernate.ejb.naming_strategy")).isNull(); }); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernatePropertiesTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernatePropertiesTests.java new file mode 100644 index 0000000000..3a3ee40e1c --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernatePropertiesTests.java @@ -0,0 +1,167 @@ +/* + * 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. + * 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.Map; +import java.util.function.Consumer; +import java.util.function.Supplier; + +import org.hibernate.cfg.AvailableSettings; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy; +import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy; +import org.springframework.boot.test.context.assertj.AssertableApplicationContext; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.test.context.runner.ContextConsumer; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +/** + * Tests for {@link HibernateProperties}. + * + * @author Stephane Nicoll + */ +public class HibernatePropertiesTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withUserConfiguration(TestConfiguration.class); + + @Mock + private Supplier ddlAutoSupplier; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void noCustomNamingStrategy() { + this.contextRunner.run(assertHibernateProperties((hibernateProperties) -> { + assertThat(hibernateProperties) + .doesNotContainKeys("hibernate.ejb.naming_strategy"); + assertThat(hibernateProperties).containsEntry( + "hibernate.physical_naming_strategy", + SpringPhysicalNamingStrategy.class.getName()); + assertThat(hibernateProperties).containsEntry( + "hibernate.implicit_naming_strategy", + SpringImplicitNamingStrategy.class.getName()); + })); + } + + @Test + public void hibernate5CustomNamingStrategies() { + this.contextRunner.withPropertyValues( + "spring.jpa.hibernate.naming.implicit-strategy:com.example.Implicit", + "spring.jpa.hibernate.naming.physical-strategy:com.example.Physical") + .run(assertHibernateProperties((hibernateProperties) -> { + assertThat(hibernateProperties).contains( + entry("hibernate.implicit_naming_strategy", + "com.example.Implicit"), + entry("hibernate.physical_naming_strategy", + "com.example.Physical")); + assertThat(hibernateProperties) + .doesNotContainKeys("hibernate.ejb.naming_strategy"); + })); + } + + @Test + public void hibernate5CustomNamingStrategiesViaJpaProperties() { + this.contextRunner.withPropertyValues( + "spring.jpa.properties.hibernate.implicit_naming_strategy:com.example.Implicit", + "spring.jpa.properties.hibernate.physical_naming_strategy:com.example.Physical") + .run(assertHibernateProperties((hibernateProperties) -> { + // You can override them as we don't provide any default + assertThat(hibernateProperties).contains( + entry("hibernate.implicit_naming_strategy", + "com.example.Implicit"), + entry("hibernate.physical_naming_strategy", + "com.example.Physical")); + assertThat(hibernateProperties) + .doesNotContainKeys("hibernate.ejb.naming_strategy"); + })); + } + + @Test + public void useNewIdGeneratorMappingsDefault() { + this.contextRunner.run(assertHibernateProperties((hibernateProperties) -> { + assertThat(hibernateProperties).containsEntry( + AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, "true"); + })); + } + + @Test + public void useNewIdGeneratorMappingsFalse() { + this.contextRunner + .withPropertyValues( + "spring.jpa.hibernate.use-new-id-generator-mappings:false") + .run(assertHibernateProperties((hibernateProperties) -> { + assertThat(hibernateProperties).containsEntry( + AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, "false"); + })); + } + + @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 assertDefaultDdlAutoNotInvoked( + String expectedDdlAuto) { + return assertHibernateProperties((hibernateProperties) -> { + assertThat(hibernateProperties).containsEntry("hibernate.hbm2ddl.auto", + expectedDdlAuto); + verify(this.ddlAutoSupplier, never()).get(); + }); + } + + private ContextConsumer assertHibernateProperties( + Consumer> consumer) { + return (context) -> { + assertThat(context).hasSingleBean(JpaProperties.class); + assertThat(context).hasSingleBean(HibernateProperties.class); + Map hibernateProperties = context + .getBean(HibernateProperties.class).determineHibernateProperties( + context.getBean(JpaProperties.class).getProperties(), + new HibernateSettings().ddlAuto(this.ddlAutoSupplier)); + consumer.accept(hibernateProperties); + }; + } + + @Configuration + @EnableConfigurationProperties({ JpaProperties.class, HibernateProperties.class }) + static class TestConfiguration { + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/JpaPropertiesTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/JpaPropertiesTests.java index a3aedabd53..2932e38928 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/JpaPropertiesTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/JpaPropertiesTests.java @@ -19,21 +19,13 @@ package org.springframework.boot.autoconfigure.orm.jpa; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.SQLException; -import java.util.Map; import java.util.function.Consumer; -import java.util.function.Supplier; import javax.sql.DataSource; -import org.hibernate.cfg.AvailableSettings; -import org.junit.Before; import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy; -import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ContextConsumer; @@ -41,7 +33,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.orm.jpa.vendor.Database; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.entry; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -57,90 +48,6 @@ public class JpaPropertiesTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withUserConfiguration(TestConfiguration.class); - @Mock - private Supplier ddlAutoSupplier; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - } - - @Test - public void noCustomNamingStrategy() { - this.contextRunner.run(assertJpaProperties((properties) -> { - Map hibernateProperties = properties - .getHibernateProperties(new HibernateSettings()); - assertThat(hibernateProperties) - .doesNotContainKeys("hibernate.ejb.naming_strategy"); - assertThat(hibernateProperties).containsEntry( - "hibernate.physical_naming_strategy", - SpringPhysicalNamingStrategy.class.getName()); - assertThat(hibernateProperties).containsEntry( - "hibernate.implicit_naming_strategy", - SpringImplicitNamingStrategy.class.getName()); - })); - } - - @Test - public void hibernate5CustomNamingStrategies() { - this.contextRunner.withPropertyValues( - "spring.jpa.hibernate.naming.implicit-strategy:com.example.Implicit", - "spring.jpa.hibernate.naming.physical-strategy:com.example.Physical") - .run(assertJpaProperties((properties) -> { - Map hibernateProperties = properties - .getHibernateProperties(new HibernateSettings()); - assertThat(hibernateProperties).contains( - entry("hibernate.implicit_naming_strategy", - "com.example.Implicit"), - entry("hibernate.physical_naming_strategy", - "com.example.Physical")); - assertThat(hibernateProperties) - .doesNotContainKeys("hibernate.ejb.naming_strategy"); - })); - } - - @Test - public void hibernate5CustomNamingStrategiesViaJpaProperties() { - this.contextRunner.withPropertyValues( - "spring.jpa.properties.hibernate.implicit_naming_strategy:com.example.Implicit", - "spring.jpa.properties.hibernate.physical_naming_strategy:com.example.Physical") - .run(assertJpaProperties((properties) -> { - Map hibernateProperties = properties - .getHibernateProperties(new HibernateSettings()); - // You can override them as we don't provide any default - assertThat(hibernateProperties).contains( - entry("hibernate.implicit_naming_strategy", - "com.example.Implicit"), - entry("hibernate.physical_naming_strategy", - "com.example.Physical")); - assertThat(hibernateProperties) - .doesNotContainKeys("hibernate.ejb.naming_strategy"); - })); - } - - @Test - public void useNewIdGeneratorMappingsDefault() { - this.contextRunner.run(assertJpaProperties((properties) -> { - Map hibernateProperties = properties - .getHibernateProperties(new HibernateSettings()); - assertThat(hibernateProperties).containsEntry( - AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, "true"); - })); - } - - @Test - public void useNewIdGeneratorMappingsFalse() { - this.contextRunner - .withPropertyValues( - "spring.jpa.hibernate.use-new-id-generator-mappings:false") - .run(assertJpaProperties((properties) -> { - Map hibernateProperties = properties - .getHibernateProperties(new HibernateSettings()); - assertThat(hibernateProperties).containsEntry( - AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, "false"); - })); - } - @Test public void determineDatabaseNoCheckIfDatabaseIsSet() { this.contextRunner.withPropertyValues("spring.jpa.database=postgresql") @@ -176,30 +83,6 @@ 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 assertDefaultDdlAutoNotInvoked( - String expectedDdlAuto) { - return assertJpaProperties((properties) -> { - Map hibernateProperties = properties.getHibernateProperties( - new HibernateSettings().ddlAuto(this.ddlAutoSupplier)); - assertThat(hibernateProperties).containsEntry("hibernate.hbm2ddl.auto", - expectedDdlAuto); - verify(this.ddlAutoSupplier, never()).get(); - }); - } - @Test public void determineDatabaseWithUnknownUrl() { this.contextRunner.run(assertJpaProperties((properties) -> {