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 b5c385699f95..7c1d44b9c475 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 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. @@ -40,6 +40,7 @@ import org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy; import org.hibernate.boot.model.naming.ImplicitNamingStrategy; import org.hibernate.boot.model.naming.PhysicalNamingStrategy; +import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.ManagedBeanSettings; import org.hibernate.cfg.SchemaToolingSettings; import org.hibernate.dialect.H2Dialect; @@ -66,6 +67,8 @@ import org.springframework.boot.autoconfigure.orm.jpa.mapping.NonAnnotatedEntity; import org.springframework.boot.autoconfigure.orm.jpa.test.City; import org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration; +import org.springframework.boot.jdbc.SchemaManagement; +import org.springframework.boot.jdbc.SchemaManagementProvider; import org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy; import org.springframework.boot.orm.jpa.hibernate.SpringJtaPlatform; import org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitialization; @@ -76,6 +79,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.orm.jpa.AbstractEntityManagerFactoryBean; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.JpaVendorAdapter; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; @@ -98,6 +102,7 @@ * @author Stephane Nicoll * @author Chris Bono * @author Moritz Halbritter + * @author Yanming Zhou */ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTests { @@ -182,6 +187,42 @@ void hibernateDialectIsSetWhenDatabasePlatformIsSet() { .contains(entry("hibernate.dialect", databasePlatform)))); } + @Test + void jpaGenerateDdlIsUsedIfHibernateHbm2ddlAutoIsNotSet() { + contextRunner().withPropertyValues("spring.jpa.generate-ddl=true") + // return "none" instead of "create-drop" + // see HibernateDefaultDdlAutoProvider.getDefaultDdlAuto(DataSource) + .withBean(SchemaManagementProvider.class, () -> (dataSource) -> SchemaManagement.MANAGED) + .run(assertEntityManagerFactoryBean((adapter) -> assertThat(adapter.getJpaPropertyMap()) + .containsEntry(AvailableSettings.HBM2DDL_AUTO, "update"))); + } + + @Test + void jpaGenerateDdlIsNotUsedIfHibernateHbm2ddlAutoIsSetToNone() { + contextRunner() + .withPropertyValues("spring.jpa.generate-ddl=true", "spring.jpa.properties.hibernate.hbm2ddl.auto=none") + .run(assertEntityManagerFactoryBean((adapter) -> assertThat(adapter.getJpaPropertyMap()) + .containsEntry(AvailableSettings.HBM2DDL_AUTO, "none"))); + } + + @Test + void jpaGenerateDdlIsNotUsedIfHibernateHbm2ddlAutoIsSetToOtherThanNone() { + contextRunner() + .withPropertyValues("spring.jpa.generate-ddl=true", "spring.jpa.properties.hibernate.hbm2ddl.auto=create") + .run(assertEntityManagerFactoryBean((adapter) -> assertThat(adapter.getJpaPropertyMap()) + .containsEntry(AvailableSettings.HBM2DDL_AUTO, "create"))); + } + + private ContextConsumer assertEntityManagerFactoryBean( + Consumer adapter) { + return (context) -> { + assertThat(context).hasSingleBean(JpaVendorAdapter.class); + assertThat(context).hasSingleBean(HibernateJpaVendorAdapter.class); + assertThat(context).hasSingleBean(AbstractEntityManagerFactoryBean.class); + adapter.accept(context.getBean(AbstractEntityManagerFactoryBean.class)); + }; + } + private ContextConsumer assertJpaVendorAdapter( Consumer adapter) { return (context) -> { diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/data/sql.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/data/sql.adoc index 71bb7b1f3de6..212baa41c568 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/data/sql.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/data/sql.adoc @@ -307,7 +307,7 @@ spring: The line in the preceding example passes a value of `true` for the `hibernate.globally_quoted_identifiers` property to the Hibernate entity manager. By default, the DDL execution (or validation) is deferred until the `ApplicationContext` has started. -There is also a `spring.jpa.generate-ddl` flag, but it is not used if Hibernate auto-configuration is active, because the `ddl-auto` settings are more fine-grained. +There is also a `spring.jpa.generate-ddl` flag, but it is not used if `spring.jpa.hibernate.ddl-auto` or `spring.jpa.properties.hibernate.hbm2ddl.auto` is present, because they are more fine-grained.