From cd05175b987c6a50f84fcd94ac53167f80a2ea00 Mon Sep 17 00:00:00 2001 From: Yanming Zhou Date: Sun, 7 Apr 2024 17:53:49 +0800 Subject: [PATCH] Correct document about `spring.jpa.generate-ddl` and add tests Closes GH-40177 --- .../HibernateJpaAutoConfigurationTests.java | 50 ++++++++++++++++++- .../modules/reference/pages/data/sql.adoc | 2 +- 2 files changed, 50 insertions(+), 2 deletions(-) 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..0be795ec116d 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. @@ -16,6 +16,7 @@ package org.springframework.boot.autoconfigure.orm.jpa; +import java.io.File; import java.io.IOException; import java.net.URL; import java.net.URLClassLoader; @@ -40,6 +41,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; @@ -76,6 +78,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 +101,7 @@ * @author Stephane Nicoll * @author Chris Bono * @author Moritz Halbritter + * @author Yanming Zhou */ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTests { @@ -182,6 +186,50 @@ void hibernateDialectIsSetWhenDatabasePlatformIsSet() { .contains(entry("hibernate.dialect", databasePlatform)))); } + @Test + void jpaGenerateDdlIsUsedIfHibernateHbm2ddlAutoIsNotSet() { + try { + contextRunner().withPropertyValues("spring.jpa.generate-ddl=true", "spring.datasource.url=jdbc:h2:./test") + // simulate non-embedded database + // see HibernateDefaultDdlAutoProvider.getDefaultDdlAuto(DataSource) + .run(assertEntityManagerFactoryBean((adapter) -> assertThat(adapter.getJpaPropertyMap()) + .containsEntry(AvailableSettings.HBM2DDL_AUTO, "update"))); + } + finally { + // cleanup H2 database file + File db = new File("test.mv.db"); + if (db.exists()) { + db.delete(); + } + } + } + + @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.