From 674b01cb06ea40f007aea6cf2f491daa7f6c7f60 Mon Sep 17 00:00:00 2001 From: bono007 Date: Sun, 7 Feb 2021 16:02:21 -0600 Subject: [PATCH] Take JPA database action into account when setting ddlAuto See gh-25129 --- .../jpa/DataSourceInitializedPublisher.java | 3 +- .../orm/jpa/HibernateProperties.java | 4 ++ .../HibernateJpaAutoConfigurationTests.java | 45 +++++++++++++++++++ .../orm/jpa/HibernatePropertiesTests.java | 14 ++++++ 4 files changed, 65 insertions(+), 1 deletion(-) 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 b935b6d097..76a4a4ee5d 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 @@ -129,7 +129,8 @@ class DataSourceInitializedPublisher implements BeanPostProcessor { : "none"); Map hibernate = this.hibernateProperties.determineHibernateProperties( this.jpaProperties.getProperties(), new HibernateSettings().ddlAuto(defaultDdlAuto)); - return hibernate.containsKey("hibernate.hbm2ddl.auto"); + return hibernate.containsKey("hibernate.hbm2ddl.auto") || !hibernate + .getOrDefault("javax.persistence.schema-generation.database.action", "none").equals("none"); } /** 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 index 208c9baa49..b7e95d9502 100644 --- 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 @@ -35,6 +35,7 @@ import org.springframework.util.StringUtils; * Configuration properties for Hibernate. * * @author Stephane Nicoll + * @author Chris Bono * @since 2.1.0 * @see JpaProperties */ @@ -129,6 +130,9 @@ public class HibernateProperties { } private String determineDdlAuto(Map existing, Supplier defaultDdlAuto) { + if (existing.get(AvailableSettings.HBM2DDL_DATABASE_ACTION) != null) { + return null; + } String ddlAuto = existing.get(AvailableSettings.HBM2DDL_AUTO); if (ddlAuto != null) { return ddlAuto; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java index 484a467787..252fc760d2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java @@ -91,6 +91,7 @@ import static org.mockito.Mockito.mock; * @author Andy Wilkinson * @author Kazuki Shimizu * @author Stephane Nicoll + * @author Chris Bono */ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTests { @@ -371,6 +372,50 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes .run((context) -> assertThat(context).doesNotHaveBean(City.class)); } + @Test + void dataSourceSchemaCreatedEventFiredWhenDdlAutoPropertyIsSet() { + dataSourceSchemaCreatedEventFired("spring.jpa.hibernate.ddl-auto:create-drop", true); + } + + @Test + void dataSourceSchemaCreatedEventNotFiredWhenDdlAutoPropertyIsSetToNone() { + dataSourceSchemaCreatedEventFired("spring.jpa.hibernate.ddl-auto:none", false); + } + + @Test + void dataSourceSchemaCreatedEventFiredWhenHibernateSpecificDdlAutoPropertyIsSet() { + dataSourceSchemaCreatedEventFired("spring.jpa.properties.hibernate.hbm2ddl.auto=create", true); + } + + @Test + void dataSourceSchemaCreatedEventNotFiredWhenHibernateSpecificDdlAutoPropertyIsSetToNone() { + dataSourceSchemaCreatedEventFired("spring.jpa.properties.hibernate.hbm2ddl.auto=none", false); + } + + @Test + void dataSourceSchemaCreatedEventFiredWhenJpaDbActionPropertyIsSet() { + dataSourceSchemaCreatedEventFired( + "spring.jpa.properties.javax.persistence.schema-generation.database.action=drop-and-create", true); + } + + @Test + void dataSourceSchemaCreatedEventNotFiredWhenJpaDbActionPropertyIsSetToNone() { + dataSourceSchemaCreatedEventFired( + "spring.jpa.properties.javax.persistence.schema-generation.database.action=none", false); + } + + private void dataSourceSchemaCreatedEventFired(String schemaGenerationPropertyWithValue, + boolean expectEventToBeFired) { + contextRunner().withUserConfiguration(JpaUsingApplicationListenerConfiguration.class) + .withPropertyValues("spring.datasource.initialization-mode=never", schemaGenerationPropertyWithValue) + .run((context) -> { + assertThat(context).hasNotFailed(); + assertThat(context.getBean(EventCapturingApplicationListener.class).events.stream() + .filter(DataSourceSchemaCreatedEvent.class::isInstance)) + .hasSize(expectEventToBeFired ? 1 : 0); + }); + } + @Test void withSyncBootstrappingAnApplicationListenerThatUsesJpaDoesNotTriggerABeanCurrentlyInCreationException() { contextRunner().withUserConfiguration(JpaUsingApplicationListenerConfiguration.class) 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 index b58da5f8d6..efb73dadcf 100644 --- 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 @@ -44,6 +44,7 @@ import static org.mockito.Mockito.verify; * * @author Stephane Nicoll * @author Artsiom Yudovin + * @author Chris Bono */ class HibernatePropertiesTests { @@ -135,6 +136,19 @@ class HibernatePropertiesTests { .run(assertDefaultDdlAutoNotInvoked("create")); } + @Test + void defaultDdlAutoIsNotInvokedAndDdlAutoIsNotSetIfJpaDbActionPropertyIsSet() { + this.contextRunner + .withPropertyValues( + "spring.jpa.properties.javax.persistence.schema-generation.database.action=drop-and-create") + .run(assertHibernateProperties((hibernateProperties) -> { + assertThat(hibernateProperties).doesNotContainKey(AvailableSettings.HBM2DDL_AUTO); + assertThat(hibernateProperties).containsEntry(AvailableSettings.HBM2DDL_DATABASE_ACTION, + "drop-and-create"); + verify(this.ddlAutoSupplier, never()).get(); + })); + } + private ContextConsumer assertDefaultDdlAutoNotInvoked(String expectedDdlAuto) { return assertHibernateProperties((hibernateProperties) -> { assertThat(hibernateProperties).containsEntry(AvailableSettings.HBM2DDL_AUTO, expectedDdlAuto);