Create spring-boot-hibernate module

Issue: 46154
This commit is contained in:
Phillip Webb 2025-06-11 17:51:30 -07:00
parent f49aaa5808
commit 9c9d6d39a2
70 changed files with 704 additions and 741 deletions

View File

@ -95,6 +95,7 @@ include "spring-boot-project:spring-boot-gson"
include "spring-boot-project:spring-boot-h2console"
include "spring-boot-project:spring-boot-hateoas"
include "spring-boot-project:spring-boot-hazelcast"
include "spring-boot-project:spring-boot-hibernate"
include "spring-boot-project:spring-boot-http-client"
include "spring-boot-project:spring-boot-http-converter"
include "spring-boot-project:spring-boot-http-codec"

View File

@ -33,7 +33,7 @@ dependencies {
implementation(project(":spring-boot-project:spring-boot-tx"))
optional(project(":spring-boot-project:spring-boot-autoconfigure"))
optional(project(":spring-boot-project:spring-boot-jpa"))
optional(project(":spring-boot-project:spring-boot-hibernate"))
optional(project(":spring-boot-project:spring-boot-observation"))
testImplementation(project(":spring-boot-project:spring-boot-flyway"))

View File

@ -70,7 +70,7 @@ import org.springframework.util.StringUtils;
* @since 4.0.0
*/
@AutoConfiguration(after = TransactionAutoConfiguration.class,
afterName = "org.springframework.boot.jpa.autoconfigure.hibernate.HibernateJpaAutoConfiguration")
afterName = "org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration")
@ConditionalOnClass({ JobLauncher.class, DataSource.class, DatabasePopulator.class })
@ConditionalOnBean({ DataSource.class, PlatformTransactionManager.class })
@ConditionalOnMissingBean(value = DefaultBatchConfiguration.class, annotation = EnableBatchProcessing.class)

View File

@ -61,12 +61,12 @@ import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
import org.springframework.boot.batch.autoconfigure.BatchAutoConfiguration.SpringBootBatchConfiguration;
import org.springframework.boot.batch.autoconfigure.domain.City;
import org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration;
import org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration;
import org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.jdbc.autoconfigure.EmbeddedDataSourceConfiguration;
import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer;
import org.springframework.boot.jpa.autoconfigure.hibernate.HibernateJpaAutoConfiguration;
import org.springframework.boot.liquibase.autoconfigure.LiquibaseAutoConfiguration;
import org.springframework.boot.sql.init.DatabaseInitializationMode;
import org.springframework.boot.sql.init.DatabaseInitializationSettings;

View File

@ -35,7 +35,7 @@ dependencies {
optional(project(":spring-boot-project:spring-boot-data-couchbase"))
optional(project(":spring-boot-project:spring-boot-data-redis"))
optional(project(":spring-boot-project:spring-boot-hazelcast"))
optional(project(":spring-boot-project:spring-boot-jpa"))
optional(project(":spring-boot-project:spring-boot-hibernate"))
optional(project(":spring-boot-project:spring-boot-metrics"))
optional("com.hazelcast:hazelcast-spring")
optional("io.micrometer:micrometer-core")

View File

@ -54,7 +54,7 @@ import org.springframework.util.Assert;
@AutoConfiguration(afterName = { "org.springframework.boot.data.couchbase.autoconfigure.CouchbaseDataAutoConfiguration",
"org.springframework.boot.data.redis.autoconfigure.RedisAutoConfiguration",
"org.springframework.boot.hazelcast.autoconfigure.HazelcastAutoConfiguration",
"org.springframework.boot.jpa.autoconfigure.hibernate.HibernateJpaAutoConfiguration" })
"org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration" })
@ConditionalOnClass(CacheManager.class)
@ConditionalOnBean(CacheAspectSupport.class)
@ConditionalOnMissingBean(value = CacheManager.class, name = "cacheResolver")

View File

@ -27,7 +27,7 @@ description = "Spring Boot Data JPA"
dependencies {
api(project(":spring-boot-project:spring-boot-data-commons"))
api(project(":spring-boot-project:spring-boot-jpa"))
api(project(":spring-boot-project:spring-boot-hibernate"))
api("org.springframework.data:spring-data-jpa")
api("org.springframework:spring-aspects")

View File

@ -30,8 +30,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration;
import org.springframework.boot.data.jpa.autoconfigure.JpaRepositoriesAutoConfiguration.JpaRepositoriesImportSelector;
import org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration;
import org.springframework.boot.jpa.autoconfigure.EntityManagerFactoryBuilderCustomizer;
import org.springframework.boot.jpa.autoconfigure.hibernate.HibernateJpaAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Import;

View File

@ -27,8 +27,8 @@ import org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfigurati
import org.springframework.boot.data.jpa.autoconfigure.domain.city.City;
import org.springframework.boot.data.jpa.autoconfigure.domain.city.CityRepository;
import org.springframework.boot.data.jpa.autoconfigure.domain.country.Country;
import org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration;
import org.springframework.boot.jdbc.autoconfigure.EmbeddedDataSourceConfiguration;
import org.springframework.boot.jpa.autoconfigure.hibernate.HibernateJpaAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

View File

@ -23,8 +23,8 @@ import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
import org.springframework.boot.data.jpa.autoconfigure.domain.city.City;
import org.springframework.boot.data.jpa.autoconfigure.domain.city.CityRepository;
import org.springframework.boot.data.web.autoconfigure.SpringDataWebAutoConfiguration;
import org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration;
import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration;
import org.springframework.boot.jpa.autoconfigure.hibernate.HibernateJpaAutoConfiguration;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.geo.Distance;

View File

@ -26,9 +26,9 @@ import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.data.jpa.autoconfigure.JpaRepositoriesAutoConfiguration;
import org.springframework.boot.data.rest.domain.city.City;
import org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration;
import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration;
import org.springframework.boot.jdbc.autoconfigure.EmbeddedDataSourceConfiguration;
import org.springframework.boot.jpa.autoconfigure.hibernate.HibernateJpaAutoConfiguration;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.boot.web.context.servlet.AnnotationConfigServletWebApplicationContext;
import org.springframework.context.annotation.Bean;

View File

@ -2022,6 +2022,7 @@ bom {
"spring-boot-h2console",
"spring-boot-hateoas",
"spring-boot-hazelcast",
"spring-boot-hibernate",
"spring-boot-http-client",
"spring-boot-http-codec",
"spring-boot-http-converter",

View File

@ -105,6 +105,7 @@ dependencies {
autoConfiguration(project(path: ":spring-boot-project:spring-boot-h2console", configuration: "autoConfigurationMetadata"))
autoConfiguration(project(path: ":spring-boot-project:spring-boot-hateoas", configuration: "autoConfigurationMetadata"))
autoConfiguration(project(path: ":spring-boot-project:spring-boot-hazelcast", configuration: "autoConfigurationMetadata"))
autoConfiguration(project(path: ":spring-boot-project:spring-boot-hibernate", configuration: "autoConfigurationMetadata"))
autoConfiguration(project(path: ":spring-boot-project:spring-boot-http-client", configuration: "autoConfigurationMetadata"))
autoConfiguration(project(path: ":spring-boot-project:spring-boot-http-converter", configuration: "autoConfigurationMetadata"))
autoConfiguration(project(path: ":spring-boot-project:spring-boot-http-codec", configuration: "autoConfigurationMetadata"))
@ -115,7 +116,6 @@ dependencies {
autoConfiguration(project(path: ":spring-boot-project:spring-boot-jetty", configuration: "autoConfigurationMetadata"))
autoConfiguration(project(path: ":spring-boot-project:spring-boot-jms", configuration: "autoConfigurationMetadata"))
autoConfiguration(project(path: ":spring-boot-project:spring-boot-jooq", configuration: "autoConfigurationMetadata"))
autoConfiguration(project(path: ":spring-boot-project:spring-boot-jpa", configuration: "autoConfigurationMetadata"))
autoConfiguration(project(path: ":spring-boot-project:spring-boot-jsonb", configuration: "autoConfigurationMetadata"))
autoConfiguration(project(path: ":spring-boot-project:spring-boot-kafka", configuration: "autoConfigurationMetadata"))
autoConfiguration(project(path: ":spring-boot-project:spring-boot-ldap", configuration: "autoConfigurationMetadata"))
@ -192,6 +192,7 @@ dependencies {
configurationProperties(project(path: ":spring-boot-project:spring-boot-h2console", configuration: "configurationPropertiesMetadata"))
configurationProperties(project(path: ":spring-boot-project:spring-boot-hateoas", configuration: "configurationPropertiesMetadata"))
configurationProperties(project(path: ":spring-boot-project:spring-boot-hazelcast", configuration: "configurationPropertiesMetadata"))
configurationProperties(project(path: ":spring-boot-project:spring-boot-hibernate", configuration: "configurationPropertiesMetadata"))
configurationProperties(project(path: ":spring-boot-project:spring-boot-http-client", configuration: "configurationPropertiesMetadata"))
configurationProperties(project(path: ":spring-boot-project:spring-boot-http-converter", configuration: "configurationPropertiesMetadata"))
configurationProperties(project(path: ":spring-boot-project:spring-boot-http-codec", configuration: "configurationPropertiesMetadata"))
@ -254,6 +255,7 @@ dependencies {
implementation(project(path: ":spring-boot-project:spring-boot-data-neo4j"))
implementation(project(path: ":spring-boot-project:spring-boot-devtools"))
implementation(project(path: ":spring-boot-project:spring-boot-docker-compose"))
implementation(project(path: ":spring-boot-project:spring-boot-hibernate"))
implementation(project(path: ":spring-boot-project:spring-boot-http-converter"))
implementation(project(path: ":spring-boot-project:spring-boot-http-codec"))
implementation(project(path: ":spring-boot-project:spring-boot-integration"))

View File

@ -18,7 +18,7 @@ package org.springframework.boot.docs.howto.dataaccess.configurehibernatesecondl
import org.hibernate.cache.jcache.ConfigSettings;
import org.springframework.boot.jpa.autoconfigure.hibernate.HibernatePropertiesCustomizer;
import org.springframework.boot.hibernate.autoconfigure.HibernatePropertiesCustomizer;
import org.springframework.cache.jcache.JCacheCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

View File

@ -17,7 +17,7 @@
package org.springframework.boot.docs.howto.dataaccess.configurehibernatesecondlevelcaching
import org.hibernate.cache.jcache.ConfigSettings
import org.springframework.boot.jpa.autoconfigure.hibernate.HibernatePropertiesCustomizer
import org.springframework.boot.hibernate.autoconfigure.HibernatePropertiesCustomizer
import org.springframework.cache.jcache.JCacheCacheManager
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

View File

@ -35,7 +35,7 @@ dependencies {
optional(project(":spring-boot-project:spring-boot-actuator-autoconfigure"))
optional(project(":spring-boot-project:spring-boot-autoconfigure"))
optional(project(":spring-boot-project:spring-boot-docker-compose"))
optional(project(":spring-boot-project:spring-boot-jpa"))
optional(project(":spring-boot-project:spring-boot-hibernate"))
optional(project(":spring-boot-project:spring-boot-testcontainers"))
optional("com.hazelcast:hazelcast-spring")
optional("org.slf4j:slf4j-api")
@ -47,6 +47,7 @@ dependencies {
testCompileOnly("com.fasterxml.jackson.core:jackson-annotations")
testImplementation(project(":spring-boot-project:spring-boot-hibernate"))
testImplementation(project(":spring-boot-project:spring-boot-test"))
testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support"))
testImplementation(testFixtures(project(":spring-boot-project:spring-boot-testcontainers")))

View File

@ -39,7 +39,7 @@ import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
* @since 4.0.0
*/
@AutoConfiguration(after = HazelcastAutoConfiguration.class,
afterName = "org.springframework.boot.jpa.autoconfigure.hibernate.HibernateJpaAutoConfiguration")
afterName = "org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration")
@ConditionalOnClass({ HazelcastInstance.class, LocalContainerEntityManagerFactoryBean.class })
@Import(HazelcastInstanceEntityManagerFactoryDependsOnConfiguration.class)
public class HazelcastJpaDependencyAutoConfiguration {

View File

@ -27,9 +27,9 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.hazelcast.autoconfigure.HazelcastJpaDependencyAutoConfiguration.HazelcastInstanceEntityManagerFactoryDependsOnPostProcessor;
import org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration;
import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration;
import org.springframework.boot.jpa.autoconfigure.EntityManagerFactoryDependsOnPostProcessor;
import org.springframework.boot.jpa.autoconfigure.hibernate.HibernateJpaAutoConfiguration;
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean;

View File

@ -0,0 +1,57 @@
/*
* Copyright 2012-present 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
*
* https://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.
*/
plugins {
id "java-library"
id "org.springframework.boot.auto-configuration"
id "org.springframework.boot.configuration-properties"
id "org.springframework.boot.deployed"
id "org.springframework.boot.optional-dependencies"
}
description = "Spring Boot Hibernate"
dependencies {
api(project(":spring-boot-project:spring-boot-jpa"))
api("org.hibernate.orm:hibernate-core")
api("org.springframework:spring-orm")
optional(project(":spring-boot-project:spring-boot-autoconfigure"))
optional(project(":spring-boot-project:spring-boot-metrics"))
optional("org.hibernate.orm:hibernate-micrometer")
testImplementation(project(":spring-boot-project:spring-boot-flyway"))
testImplementation(project(":spring-boot-project:spring-boot-liquibase"))
testImplementation(project(":spring-boot-project:spring-boot-test"))
testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support"))
testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure")))
testImplementation("com.zaxxer:HikariCP")
testImplementation("javax.cache:cache-api")
testImplementation("org.ehcache:ehcache") {
artifact {
classifier = 'jakarta'
}
}
testImplementation("jakarta.servlet:jakarta.servlet-api")
testImplementation("org.hibernate.orm:hibernate-envers")
testImplementation("org.hibernate.orm:hibernate-jcache")
testImplementation("org.springframework:spring-context-support")
testImplementation("org.springframework:spring-webmvc")
testRuntimeOnly("ch.qos.logback:logback-classic")
testRuntimeOnly("com.h2database:h2")
}

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.jpa.hibernate;
package org.springframework.boot.hibernate;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.ImplicitJoinTableNameSource;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.jpa.hibernate;
package org.springframework.boot.hibernate;
import jakarta.transaction.TransactionManager;
import jakarta.transaction.UserTransaction;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.jpa.autoconfigure.hibernate;
package org.springframework.boot.hibernate.autoconfigure;
import java.util.stream.StreamSupport;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.jpa.autoconfigure.hibernate;
package org.springframework.boot.hibernate.autoconfigure;
import jakarta.persistence.EntityManager;
import org.hibernate.engine.spi.SessionImplementor;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.jpa.autoconfigure.hibernate;
package org.springframework.boot.hibernate.autoconfigure;
import java.util.ArrayList;
import java.util.Arrays;
@ -44,15 +44,15 @@ import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.hibernate.SpringImplicitNamingStrategy;
import org.springframework.boot.hibernate.SpringJtaPlatform;
import org.springframework.boot.hibernate.autoconfigure.HibernateJpaConfiguration.HibernateRuntimeHints;
import org.springframework.boot.jdbc.SchemaManagementProvider;
import org.springframework.boot.jdbc.metadata.CompositeDataSourcePoolMetadataProvider;
import org.springframework.boot.jdbc.metadata.DataSourcePoolMetadata;
import org.springframework.boot.jdbc.metadata.DataSourcePoolMetadataProvider;
import org.springframework.boot.jpa.autoconfigure.JpaBaseConfiguration;
import org.springframework.boot.jpa.autoconfigure.JpaProperties;
import org.springframework.boot.jpa.autoconfigure.hibernate.HibernateJpaConfiguration.HibernateRuntimeHints;
import org.springframework.boot.jpa.hibernate.SpringImplicitNamingStrategy;
import org.springframework.boot.jpa.hibernate.SpringJtaPlatform;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportRuntimeHints;
import org.springframework.jdbc.support.SQLExceptionTranslator;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.jpa.hibernate.metrics.autoconfigure;
package org.springframework.boot.hibernate.autoconfigure;
import java.util.Collections;
import java.util.Map;
@ -32,7 +32,6 @@ import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.jpa.autoconfigure.hibernate.HibernateJpaAutoConfiguration;
import org.springframework.util.StringUtils;
/**

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.jpa.autoconfigure.hibernate;
package org.springframework.boot.hibernate.autoconfigure;
import java.util.Collection;
import java.util.HashMap;
@ -27,8 +27,8 @@ import org.hibernate.cfg.PersistenceSettings;
import org.hibernate.cfg.SchemaToolingSettings;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.hibernate.SpringImplicitNamingStrategy;
import org.springframework.boot.jpa.autoconfigure.JpaProperties;
import org.springframework.boot.jpa.hibernate.SpringImplicitNamingStrategy;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.jpa.autoconfigure.hibernate;
package org.springframework.boot.hibernate.autoconfigure;
import java.util.Map;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.jpa.autoconfigure.hibernate;
package org.springframework.boot.hibernate.autoconfigure;
import java.util.ArrayList;
import java.util.Collection;

View File

@ -17,4 +17,4 @@
/**
* Auto-configuration for JPA and Spring ORM.
*/
package org.springframework.boot.jpa.autoconfigure.hibernate;
package org.springframework.boot.hibernate.autoconfigure;

View File

@ -17,4 +17,4 @@
/**
* Hibernate Support classes.
*/
package org.springframework.boot.jpa.hibernate;
package org.springframework.boot.hibernate;

View File

@ -0,0 +1,75 @@
{
"groups": [],
"properties": [
{
"name": "spring.jpa.hibernate.use-new-id-generator-mappings",
"type": "java.lang.Boolean",
"description": "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\".",
"deprecation": {
"level": "error",
"reason": "Hibernate no longer supports disabling the use of new ID generator mappings."
}
}
],
"hints": [
{
"name": "spring.jpa.hibernate.ddl-auto",
"values": [
{
"value": "create",
"description": "Create the schema and destroy previous data."
},
{
"value": "create-drop",
"description": "Create and then destroy the schema at the end of the session."
},
{
"value": "create-only",
"description": "Create the schema."
},
{
"value": "drop",
"description": "Drop the schema."
},
{
"value": "none",
"description": "Disable DDL handling."
},
{
"value": "truncate",
"description": "Truncate the tables in the schema."
},
{
"value": "update",
"description": "Update the schema if necessary."
},
{
"value": "validate",
"description": "Validate the schema, make no changes to the database."
}
]
},
{
"name": "spring.jpa.hibernate.naming.implicit-strategy",
"providers": [
{
"name": "class-reference",
"parameters": {
"target": "org.hibernate.boot.model.naming.ImplicitNamingStrategy"
}
}
]
},
{
"name": "spring.jpa.hibernate.naming.physical-strategy",
"providers": [
{
"name": "class-reference",
"parameters": {
"target": "org.hibernate.boot.model.naming.PhysicalNamingStrategy"
}
}
]
}
]
}

View File

@ -0,0 +1,2 @@
org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration
org.springframework.boot.hibernate.autoconfigure.HibernateMetricsAutoConfiguration

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.jpa.autoconfigure.hibernate;
package org.springframework.boot.hibernate.autoconfigure;
import java.sql.Connection;
import java.sql.DatabaseMetaData;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.jpa.autoconfigure.hibernate;
package org.springframework.boot.hibernate.autoconfigure;
import javax.cache.CacheManager;
import javax.cache.Caching;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.jpa.autoconfigure.hibernate;
package org.springframework.boot.hibernate.autoconfigure;
import java.util.Collections;

View File

@ -14,9 +14,14 @@
* limitations under the License.
*/
package org.springframework.boot.jpa.autoconfigure.hibernate;
package org.springframework.boot.hibernate.autoconfigure;
import java.io.File;
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
@ -26,6 +31,8 @@ import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.function.Consumer;
import javax.sql.DataSource;
@ -33,6 +40,8 @@ import javax.sql.DataSource;
import com.zaxxer.hikari.HikariDataSource;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.metamodel.ManagedType;
import jakarta.persistence.spi.PersistenceUnitInfo;
import jakarta.transaction.Synchronization;
import jakarta.transaction.Transaction;
import jakarta.transaction.TransactionManager;
@ -59,27 +68,40 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
import org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration;
import org.springframework.boot.hibernate.SpringImplicitNamingStrategy;
import org.springframework.boot.hibernate.SpringJtaPlatform;
import org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfigurationTests.JpaUsingApplicationListenerConfiguration.EventCapturingApplicationListener;
import org.springframework.boot.hibernate.autoconfigure.HibernateJpaConfiguration.HibernateRuntimeHints;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration;
import org.springframework.boot.jdbc.autoconfigure.DataSourceInitializationAutoConfiguration;
import org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.jdbc.autoconfigure.XADataSourceAutoConfiguration;
import org.springframework.boot.jpa.autoconfigure.AbstractJpaAutoConfigurationTests;
import org.springframework.boot.jpa.EntityManagerFactoryBuilder;
import org.springframework.boot.jpa.autoconfigure.EntityManagerFactoryBuilderCustomizer;
import org.springframework.boot.jpa.autoconfigure.hibernate.HibernateJpaAutoConfigurationTests.JpaUsingApplicationListenerConfiguration.EventCapturingApplicationListener;
import org.springframework.boot.jpa.autoconfigure.hibernate.HibernateJpaConfiguration.HibernateRuntimeHints;
import org.springframework.boot.jpa.autoconfigure.JpaBaseConfiguration;
import org.springframework.boot.jpa.autoconfigure.JpaProperties;
import org.springframework.boot.jpa.autoconfigure.hibernate.mapping.NonAnnotatedEntity;
import org.springframework.boot.jpa.autoconfigure.test.city.City;
import org.springframework.boot.jpa.hibernate.SpringImplicitNamingStrategy;
import org.springframework.boot.jpa.hibernate.SpringJtaPlatform;
import org.springframework.boot.jpa.autoconfigure.test.country.Country;
import org.springframework.boot.liquibase.autoconfigure.LiquibaseAutoConfiguration;
import org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitialization;
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.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.testsupport.BuildOutput;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration;
import org.springframework.boot.transaction.autoconfigure.TransactionManagerCustomizationAutoConfiguration;
import org.springframework.boot.transaction.jta.autoconfigure.JtaAutoConfiguration;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.SQLExceptionTranslator;
@ -87,8 +109,15 @@ import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager;
import org.springframework.orm.jpa.persistenceunit.ManagedClassNameFilter;
import org.springframework.orm.jpa.persistenceunit.PersistenceManagedTypes;
import org.springframework.orm.jpa.persistenceunit.PersistenceUnitManager;
import org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter;
import org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.jta.JtaTransactionManager;
import static org.assertj.core.api.Assertions.assertThat;
@ -97,25 +126,243 @@ import static org.assertj.core.api.Assertions.entry;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link HibernateJpaAutoConfiguration}.
* Base for JPA tests and tests for {@link JpaBaseConfiguration}.
*
* @author Dave Syer
* @author Phillip Webb
* @author Dave Syer
* @author Stephane Nicoll
* @author Yanming Zhou
* @author Andy Wilkinson
* @author Kazuki Shimizu
* @author Stephane Nicoll
* @author Chris Bono
* @author Moritz Halbritter
*/
class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTests {
class HibernateJpaAutoConfigurationTests {
HibernateJpaAutoConfigurationTests() {
super(HibernateJpaAutoConfiguration.class);
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withPropertyValues("spring.datasource.generate-unique-name=true",
"spring.jta.log-dir=" + new File(new BuildOutput(getClass()).getRootLocation(), "transaction-logs"))
.withUserConfiguration(TestConfiguration.class)
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, TransactionAutoConfiguration.class,
TransactionManagerCustomizationAutoConfiguration.class, DataSourceInitializationAutoConfiguration.class,
HibernateJpaAutoConfiguration.class));
@Test
void notConfiguredIfDataSourceIsNotAvailable() {
new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(HibernateJpaAutoConfiguration.class))
.run(assertJpaIsNotAutoConfigured());
}
@Test
void notConfiguredIfNoSingleDataSourceCandidateIsAvailable() {
new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(HibernateJpaAutoConfiguration.class))
.withUserConfiguration(TestTwoDataSourcesConfiguration.class)
.run(assertJpaIsNotAutoConfigured());
}
protected ContextConsumer<AssertableApplicationContext> assertJpaIsNotAutoConfigured() {
return (context) -> {
assertThat(context).hasNotFailed();
assertThat(context).hasSingleBean(JpaProperties.class);
assertThat(context).doesNotHaveBean(TransactionManager.class);
assertThat(context).doesNotHaveBean(EntityManagerFactory.class);
};
}
@Test
void configuredWithAutoConfiguredDataSource() {
this.contextRunner.run((context) -> {
assertThat(context).hasSingleBean(DataSource.class);
assertThat(context).hasSingleBean(JpaTransactionManager.class);
assertThat(context).hasSingleBean(EntityManagerFactory.class);
assertThat(context).hasSingleBean(PersistenceManagedTypes.class);
});
}
@Test
void configuredWithSingleCandidateDataSource() {
this.contextRunner.withUserConfiguration(TestTwoDataSourcesAndPrimaryConfiguration.class).run((context) -> {
assertThat(context).getBeans(DataSource.class).hasSize(2);
assertThat(context).hasSingleBean(JpaTransactionManager.class);
assertThat(context).hasSingleBean(EntityManagerFactory.class);
assertThat(context).hasSingleBean(PersistenceManagedTypes.class);
});
}
@Test
void jpaTransactionManagerTakesPrecedenceOverSimpleDataSourceOne() {
this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceTransactionManagerAutoConfiguration.class))
.run((context) -> {
assertThat(context).hasSingleBean(DataSource.class);
assertThat(context).hasSingleBean(JpaTransactionManager.class);
assertThat(context).getBean("transactionManager").isInstanceOf(JpaTransactionManager.class);
});
}
@Test
void openEntityManagerInViewInterceptorIsCreated() {
new WebApplicationContextRunner().withPropertyValues("spring.datasource.generate-unique-name=true")
.withUserConfiguration(TestConfiguration.class)
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class,
TransactionAutoConfiguration.class, HibernateJpaAutoConfiguration.class))
.run((context) -> assertThat(context).hasSingleBean(OpenEntityManagerInViewInterceptor.class));
}
@Test
void openEntityManagerInViewInterceptorIsNotRegisteredWhenFilterPresent() {
new WebApplicationContextRunner().withPropertyValues("spring.datasource.generate-unique-name=true")
.withUserConfiguration(TestFilterConfiguration.class)
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class,
TransactionAutoConfiguration.class, HibernateJpaAutoConfiguration.class))
.run((context) -> assertThat(context).doesNotHaveBean(OpenEntityManagerInViewInterceptor.class));
}
@Test
void openEntityManagerInViewInterceptorIsNotRegisteredWhenFilterRegistrationPresent() {
new WebApplicationContextRunner().withPropertyValues("spring.datasource.generate-unique-name=true")
.withUserConfiguration(TestFilterRegistrationConfiguration.class)
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class,
TransactionAutoConfiguration.class, HibernateJpaAutoConfiguration.class))
.run((context) -> assertThat(context).doesNotHaveBean(OpenEntityManagerInViewInterceptor.class));
}
@Test
void openEntityManagerInViewInterceptorAutoConfigurationBacksOffWhenManuallyRegistered() {
new WebApplicationContextRunner().withPropertyValues("spring.datasource.generate-unique-name=true")
.withUserConfiguration(TestInterceptorManualConfiguration.class)
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class,
TransactionAutoConfiguration.class, HibernateJpaAutoConfiguration.class))
.run((context) -> assertThat(context).getBean(OpenEntityManagerInViewInterceptor.class)
.isExactlyInstanceOf(
TestInterceptorManualConfiguration.ManualOpenEntityManagerInViewInterceptor.class));
}
@Test
void openEntityManagerInViewInterceptorIsNotRegisteredWhenExplicitlyOff() {
new WebApplicationContextRunner()
.withPropertyValues("spring.datasource.generate-unique-name=true", "spring.jpa.open-in-view=false")
.withUserConfiguration(TestConfiguration.class)
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class,
TransactionAutoConfiguration.class, HibernateJpaAutoConfiguration.class))
.run((context) -> assertThat(context).doesNotHaveBean(OpenEntityManagerInViewInterceptor.class));
}
@Test
void customJpaProperties() {
this.contextRunner
.withPropertyValues("spring.jpa.properties.a:b", "spring.jpa.properties.a.b:c", "spring.jpa.properties.c:d")
.run((context) -> {
LocalContainerEntityManagerFactoryBean bean = context
.getBean(LocalContainerEntityManagerFactoryBean.class);
Map<String, Object> map = bean.getJpaPropertyMap();
assertThat(map).containsEntry("a", "b");
assertThat(map).containsEntry("c", "d");
assertThat(map).containsEntry("a.b", "c");
});
}
@Test
@WithMetaInfPersistenceXmlResource
void usesManuallyDefinedLocalContainerEntityManagerFactoryBeanUsingBuilder() {
this.contextRunner.withPropertyValues("spring.jpa.properties.a=b")
.withUserConfiguration(TestConfigurationWithEntityManagerFactoryBuilder.class)
.run((context) -> {
LocalContainerEntityManagerFactoryBean factoryBean = context
.getBean(LocalContainerEntityManagerFactoryBean.class);
Map<String, Object> map = factoryBean.getJpaPropertyMap();
assertThat(map).containsEntry("configured", "manually").containsEntry("a", "b");
});
}
@Test
@WithMetaInfPersistenceXmlResource
void usesManuallyDefinedLocalContainerEntityManagerFactoryBeanIfAvailable() {
this.contextRunner.withUserConfiguration(TestConfigurationWithLocalContainerEntityManagerFactoryBean.class)
.run((context) -> {
LocalContainerEntityManagerFactoryBean factoryBean = context
.getBean(LocalContainerEntityManagerFactoryBean.class);
Map<String, Object> map = factoryBean.getJpaPropertyMap();
assertThat(map).containsEntry("configured", "manually");
});
}
@Test
@WithMetaInfPersistenceXmlResource
void usesManuallyDefinedEntityManagerFactoryIfAvailable() {
this.contextRunner.withUserConfiguration(TestConfigurationWithLocalContainerEntityManagerFactoryBean.class)
.run((context) -> {
EntityManagerFactory factoryBean = context.getBean(EntityManagerFactory.class);
Map<String, Object> map = factoryBean.getProperties();
assertThat(map).containsEntry("configured", "manually");
});
}
@Test
void usesManuallyDefinedTransactionManagerBeanIfAvailable() {
this.contextRunner.withUserConfiguration(TestConfigurationWithTransactionManager.class).run((context) -> {
assertThat(context).hasSingleBean(JpaTransactionManager.class);
JpaTransactionManager txManager = context.getBean(JpaTransactionManager.class);
assertThat(txManager).isInstanceOf(CustomJpaTransactionManager.class);
});
}
@Test
void defaultPersistenceManagedTypes() {
this.contextRunner.run((context) -> {
assertThat(context).hasSingleBean(PersistenceManagedTypes.class);
EntityManager entityManager = context.getBean(EntityManagerFactory.class).createEntityManager();
assertThat(getManagedJavaTypes(entityManager)).contains(City.class).doesNotContain(Country.class);
});
}
@Test
void customPersistenceManagedTypes() {
this.contextRunner
.withBean(PersistenceManagedTypes.class, () -> PersistenceManagedTypes.of(Country.class.getName()))
.run((context) -> {
assertThat(context).hasSingleBean(PersistenceManagedTypes.class);
EntityManager entityManager = context.getBean(EntityManagerFactory.class).createEntityManager();
assertThat(getManagedJavaTypes(entityManager)).contains(Country.class).doesNotContain(City.class);
});
}
@Test
void customPersistenceUnitManager() {
this.contextRunner.withUserConfiguration(TestConfigurationWithCustomPersistenceUnitManager.class)
.run((context) -> {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = context
.getBean(LocalContainerEntityManagerFactoryBean.class);
assertThat(entityManagerFactoryBean).hasFieldOrPropertyWithValue("persistenceUnitManager",
context.getBean(PersistenceUnitManager.class));
});
}
@Test
void customPersistenceUnitPostProcessors() {
this.contextRunner.withUserConfiguration(TestConfigurationWithCustomPersistenceUnitPostProcessors.class)
.run((context) -> {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = context
.getBean(LocalContainerEntityManagerFactoryBean.class);
PersistenceUnitInfo persistenceUnitInfo = entityManagerFactoryBean.getPersistenceUnitInfo();
assertThat(persistenceUnitInfo).isNotNull();
assertThat(persistenceUnitInfo.getManagedClassNames())
.contains("customized.attribute.converter.class.name");
});
}
@Test
void customManagedClassNameFilter() {
this.contextRunner.withBean(ManagedClassNameFilter.class, () -> (s) -> !s.endsWith("City"))
.withUserConfiguration(AutoConfigurePackageForCountry.class)
.run((context) -> {
EntityManager entityManager = context.getBean(EntityManagerFactory.class).createEntityManager();
assertThat(getManagedJavaTypes(entityManager)).contains(Country.class).doesNotContain(City.class);
});
}
@Test
void testDmlScriptWithMissingDdl() {
contextRunner().withPropertyValues("spring.sql.init.data-locations:classpath:/city.sql",
this.contextRunner.withPropertyValues("spring.sql.init.data-locations:classpath:/city.sql",
// Missing:
"spring.sql.init.schema-locations:classpath:/ddl.sql")
.run((context) -> {
@ -128,7 +375,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
void testDmlScript() {
// This can't succeed because the data SQL is executed immediately after the
// schema and Hibernate hasn't initialized yet at that point
contextRunner().withPropertyValues("spring.sql.init.data-locations:/city.sql").run((context) -> {
this.contextRunner.withPropertyValues("spring.sql.init.data-locations:/city.sql").run((context) -> {
assertThat(context).hasFailed();
assertThat(context.getStartupFailure()).isInstanceOf(BeanCreationException.class);
});
@ -138,7 +385,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@WithResource(name = "city.sql",
content = "INSERT INTO CITY (ID, NAME, STATE, COUNTRY, MAP) values (2000, 'Washington', 'DC', 'US', 'Google')")
void testDmlScriptRunsEarly() {
contextRunner().withUserConfiguration(TestInitializedJpaConfiguration.class)
this.contextRunner.withUserConfiguration(TestInitializedJpaConfiguration.class)
.withClassLoader(new HideDataScriptClassLoader())
.withPropertyValues("spring.jpa.show-sql=true", "spring.jpa.properties.hibernate.format_sql=true",
"spring.jpa.properties.hibernate.highlight_sql=true", "spring.jpa.hibernate.ddl-auto:create-drop",
@ -158,7 +405,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
);
""")
void testFlywaySwitchOffDdlAuto() {
contextRunner().withPropertyValues("spring.sql.init.mode:never", "spring.flyway.locations:classpath:db/city")
this.contextRunner.withPropertyValues("spring.sql.init.mode:never", "spring.flyway.locations:classpath:db/city")
.withConfiguration(AutoConfigurations.of(FlywayAutoConfiguration.class))
.run((context) -> assertThat(context).hasNotFailed());
}
@ -176,7 +423,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
);
""")
void testFlywayPlusValidation() {
contextRunner()
this.contextRunner
.withPropertyValues("spring.sql.init.mode:never", "spring.flyway.locations:classpath:db/city",
"spring.jpa.hibernate.ddl-auto:validate")
.withConfiguration(AutoConfigurations.of(FlywayAutoConfiguration.class))
@ -225,7 +472,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
nullable: true
""")
void testLiquibasePlusValidation() {
contextRunner()
this.contextRunner
.withPropertyValues("spring.liquibase.change-log:classpath:db/changelog/db.changelog-city.yaml",
"spring.jpa.hibernate.ddl-auto:validate")
.withConfiguration(AutoConfigurations.of(LiquibaseAutoConfiguration.class))
@ -234,14 +481,14 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@Test
void hibernateDialectIsNotSetByDefault() {
contextRunner().run(assertJpaVendorAdapter(
this.contextRunner.run(assertJpaVendorAdapter(
(adapter) -> assertThat(adapter.getJpaPropertyMap()).doesNotContainKeys("hibernate.dialect")));
}
@Test
void shouldConfigureHibernateJpaDialectWithSqlExceptionTranslatorIfPresent() {
SQLStateSQLExceptionTranslator sqlExceptionTranslator = new SQLStateSQLExceptionTranslator();
contextRunner().withBean(SQLStateSQLExceptionTranslator.class, () -> sqlExceptionTranslator)
this.contextRunner.withBean(SQLStateSQLExceptionTranslator.class, () -> sqlExceptionTranslator)
.run(assertJpaVendorAdapter(
(adapter) -> assertThat(adapter.getJpaDialect()).extracting("exceptionTranslator")
.hasFieldOrPropertyWithValue("jdbcExceptionTranslator", sqlExceptionTranslator)));
@ -251,7 +498,8 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
void shouldNotConfigureHibernateJpaDialectWithSqlExceptionTranslatorIfNotUnique() {
SQLStateSQLExceptionTranslator sqlExceptionTranslator1 = new SQLStateSQLExceptionTranslator();
SQLStateSQLExceptionTranslator sqlExceptionTranslator2 = new SQLStateSQLExceptionTranslator();
contextRunner().withBean("sqlExceptionTranslator1", SQLExceptionTranslator.class, () -> sqlExceptionTranslator1)
this.contextRunner
.withBean("sqlExceptionTranslator1", SQLExceptionTranslator.class, () -> sqlExceptionTranslator1)
.withBean("sqlExceptionTranslator2", SQLExceptionTranslator.class, () -> sqlExceptionTranslator2)
.run(assertJpaVendorAdapter(
(adapter) -> assertThat(adapter.getJpaDialect()).extracting("exceptionTranslator")
@ -260,7 +508,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@Test
void hibernateDialectIsSetWhenDatabaseIsSet() {
contextRunner().withPropertyValues("spring.jpa.database=H2")
this.contextRunner.withPropertyValues("spring.jpa.database=H2")
.run(assertJpaVendorAdapter((adapter) -> assertThat(adapter.getJpaPropertyMap())
.contains(entry("hibernate.dialect", H2Dialect.class.getName()))));
}
@ -268,7 +516,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@Test
void hibernateDialectIsSetWhenDatabasePlatformIsSet() {
String databasePlatform = TestH2Dialect.class.getName();
contextRunner().withPropertyValues("spring.jpa.database-platform=" + databasePlatform)
this.contextRunner.withPropertyValues("spring.jpa.database-platform=" + databasePlatform)
.run(assertJpaVendorAdapter((adapter) -> assertThat(adapter.getJpaPropertyMap())
.contains(entry("hibernate.dialect", databasePlatform))));
}
@ -284,13 +532,13 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@Test
void jtaDefaultPlatform() {
contextRunner().withUserConfiguration(JtaTransactionManagerConfiguration.class)
this.contextRunner.withUserConfiguration(JtaTransactionManagerConfiguration.class)
.run(assertJtaPlatform(SpringJtaPlatform.class));
}
@Test
void jtaCustomPlatform() {
contextRunner()
this.contextRunner
.withPropertyValues(
"spring.jpa.properties.hibernate.transaction.jta.platform:" + TestJtaPlatform.class.getName())
.withConfiguration(AutoConfigurations.of(JtaAutoConfiguration.class))
@ -299,7 +547,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@Test
void jtaNotUsedByTheApplication() {
contextRunner().run(assertJtaPlatform(NoJtaPlatform.class));
this.contextRunner.run(assertJtaPlatform(NoJtaPlatform.class));
}
private ContextConsumer<AssertableApplicationContext> assertJtaPlatform(Class<? extends JtaPlatform> expectedType) {
@ -313,7 +561,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@Test
void jtaCustomTransactionManagerUsingProperties() {
contextRunner()
this.contextRunner
.withPropertyValues("spring.transaction.default-timeout:30",
"spring.transaction.rollback-on-commit-failure:true")
.run((context) -> {
@ -325,7 +573,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@Test
void autoConfigurationBacksOffWithSeveralDataSources() {
contextRunner()
this.contextRunner
.withConfiguration(AutoConfigurations.of(DataSourceTransactionManagerAutoConfiguration.class,
XADataSourceAutoConfiguration.class, JtaAutoConfiguration.class))
.withUserConfiguration(TestTwoDataSourcesConfiguration.class)
@ -337,7 +585,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@Test
void providerDisablesAutoCommitIsConfigured() {
contextRunner()
this.contextRunner
.withPropertyValues("spring.datasource.type:" + HikariDataSource.class.getName(),
"spring.datasource.hikari.auto-commit:false")
.run((context) -> {
@ -349,7 +597,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@Test
void providerDisablesAutoCommitIsNotConfiguredIfAutoCommitIsEnabled() {
contextRunner()
this.contextRunner
.withPropertyValues("spring.datasource.type:" + HikariDataSource.class.getName(),
"spring.datasource.hikari.auto-commit:true")
.run((context) -> {
@ -361,7 +609,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@Test
void providerDisablesAutoCommitIsNotConfiguredIfPropertyIsSet() {
contextRunner()
this.contextRunner
.withPropertyValues("spring.datasource.type:" + HikariDataSource.class.getName(),
"spring.datasource.hikari.auto-commit:false",
"spring.jpa.properties.hibernate.connection.provider_disables_autocommit=false")
@ -374,7 +622,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@Test
void providerDisablesAutoCommitIsNotConfiguredWithJta() {
contextRunner().withUserConfiguration(JtaTransactionManagerConfiguration.class)
this.contextRunner.withUserConfiguration(JtaTransactionManagerConfiguration.class)
.withPropertyValues("spring.datasource.type:" + HikariDataSource.class.getName(),
"spring.datasource.hikari.auto-commit:false")
.run((context) -> {
@ -409,7 +657,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@WithResource(name = "non-annotated-data.sql",
content = "INSERT INTO NON_ANNOTATED (id, item) values (2000, 'Test');")
void customResourceMapping() {
contextRunner().withClassLoader(new HideDataScriptClassLoader())
this.contextRunner.withClassLoader(new HideDataScriptClassLoader())
.withPropertyValues("spring.sql.init.data-locations:classpath:non-annotated-data.sql",
"spring.jpa.mapping-resources=META-INF/mappings/non-annotated.xml",
"spring.jpa.defer-datasource-initialization=true")
@ -423,7 +671,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@Test
void physicalNamingStrategyCanBeUsed() {
contextRunner().withUserConfiguration(TestPhysicalNamingStrategyConfiguration.class).run((context) -> {
this.contextRunner.withUserConfiguration(TestPhysicalNamingStrategyConfiguration.class).run((context) -> {
Map<String, Object> hibernateProperties = getVendorProperties(context);
assertThat(hibernateProperties)
.contains(entry("hibernate.physical_naming_strategy", context.getBean("testPhysicalNamingStrategy")));
@ -433,7 +681,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@Test
void implicitNamingStrategyCanBeUsed() {
contextRunner().withUserConfiguration(TestImplicitNamingStrategyConfiguration.class).run((context) -> {
this.contextRunner.withUserConfiguration(TestImplicitNamingStrategyConfiguration.class).run((context) -> {
Map<String, Object> hibernateProperties = getVendorProperties(context);
assertThat(hibernateProperties)
.contains(entry("hibernate.implicit_naming_strategy", context.getBean("testImplicitNamingStrategy")));
@ -443,7 +691,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@Test
void namingStrategyInstancesTakePrecedenceOverNamingStrategyProperties() {
contextRunner()
this.contextRunner
.withUserConfiguration(TestPhysicalNamingStrategyConfiguration.class,
TestImplicitNamingStrategyConfiguration.class)
.withPropertyValues("spring.jpa.hibernate.naming.physical-strategy:com.example.Physical",
@ -459,7 +707,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@Test
void hibernatePropertiesCustomizerTakesPrecedenceOverStrategyInstancesAndNamingStrategyProperties() {
contextRunner()
this.contextRunner
.withUserConfiguration(TestHibernatePropertiesCustomizerConfiguration.class,
TestPhysicalNamingStrategyConfiguration.class, TestImplicitNamingStrategyConfiguration.class)
.withPropertyValues("spring.jpa.hibernate.naming.physical-strategy:com.example.Physical",
@ -479,7 +727,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@WithResource(name = "city.sql",
content = "INSERT INTO CITY (ID, NAME, STATE, COUNTRY, MAP) values (2000, 'Washington', 'DC', 'US', 'Google')")
void eventListenerCanBeRegisteredAsBeans() {
contextRunner().withUserConfiguration(TestInitializedJpaConfiguration.class)
this.contextRunner.withUserConfiguration(TestInitializedJpaConfiguration.class)
.withClassLoader(new HideDataScriptClassLoader())
.withPropertyValues("spring.jpa.show-sql=true", "spring.jpa.hibernate.ddl-auto:create-drop",
"spring.sql.init.data-locations:classpath:/city.sql",
@ -493,13 +741,13 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@Test
void hibernatePropertiesCustomizerCanDisableBeanContainer() {
contextRunner().withUserConfiguration(DisableBeanContainerConfiguration.class)
this.contextRunner.withUserConfiguration(DisableBeanContainerConfiguration.class)
.run((context) -> assertThat(context).doesNotHaveBean(City.class));
}
@Test
void vendorPropertiesWithEmbeddedDatabaseAndNoDdlProperty() {
contextRunner().run(vendorProperties((vendorProperties) -> {
this.contextRunner.run(vendorProperties((vendorProperties) -> {
assertThat(vendorProperties).doesNotContainKeys(SchemaToolingSettings.JAKARTA_HBM2DDL_DATABASE_ACTION);
assertThat(vendorProperties).containsEntry(SchemaToolingSettings.HBM2DDL_AUTO, "create-drop");
}));
@ -507,7 +755,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@Test
void vendorPropertiesWhenDdlAutoPropertyIsSet() {
contextRunner().withPropertyValues("spring.jpa.hibernate.ddl-auto=update")
this.contextRunner.withPropertyValues("spring.jpa.hibernate.ddl-auto=update")
.run(vendorProperties((vendorProperties) -> {
assertThat(vendorProperties).doesNotContainKeys(SchemaToolingSettings.JAKARTA_HBM2DDL_DATABASE_ACTION);
assertThat(vendorProperties).containsEntry(SchemaToolingSettings.HBM2DDL_AUTO, "update");
@ -516,7 +764,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@Test
void vendorPropertiesWhenDdlAutoPropertyAndHibernatePropertiesAreSet() {
contextRunner()
this.contextRunner
.withPropertyValues("spring.jpa.hibernate.ddl-auto=update",
"spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop")
.run(vendorProperties((vendorProperties) -> {
@ -527,14 +775,14 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@Test
void vendorPropertiesWhenDdlAutoPropertyIsSetToNone() {
contextRunner().withPropertyValues("spring.jpa.hibernate.ddl-auto=none")
this.contextRunner.withPropertyValues("spring.jpa.hibernate.ddl-auto=none")
.run(vendorProperties((vendorProperties) -> assertThat(vendorProperties).doesNotContainKeys(
SchemaToolingSettings.JAKARTA_HBM2DDL_DATABASE_ACTION, SchemaToolingSettings.HBM2DDL_AUTO)));
}
@Test
void vendorPropertiesWhenJpaDdlActionIsSet() {
contextRunner()
this.contextRunner
.withPropertyValues("spring.jpa.properties.jakarta.persistence.schema-generation.database.action=create")
.run(vendorProperties((vendorProperties) -> {
assertThat(vendorProperties).containsEntry(SchemaToolingSettings.JAKARTA_HBM2DDL_DATABASE_ACTION,
@ -545,7 +793,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@Test
void vendorPropertiesWhenBothDdlAutoPropertiesAreSet() {
contextRunner()
this.contextRunner
.withPropertyValues("spring.jpa.properties.jakarta.persistence.schema-generation.database.action=create",
"spring.jpa.hibernate.ddl-auto=create-only")
.run(vendorProperties((vendorProperties) -> {
@ -566,7 +814,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@Test
void withSyncBootstrappingAnApplicationListenerThatUsesJpaDoesNotTriggerABeanCurrentlyInCreationException() {
contextRunner().withUserConfiguration(JpaUsingApplicationListenerConfiguration.class).run((context) -> {
this.contextRunner.withUserConfiguration(JpaUsingApplicationListenerConfiguration.class).run((context) -> {
assertThat(context).hasNotFailed();
EventCapturingApplicationListener listener = context.getBean(EventCapturingApplicationListener.class);
assertThat(listener.events).hasSize(1);
@ -576,7 +824,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@Test
void withAsyncBootstrappingAnApplicationListenerThatUsesJpaDoesNotTriggerABeanCurrentlyInCreationException() {
contextRunner()
this.contextRunner
.withUserConfiguration(AsyncBootstrappingConfiguration.class,
JpaUsingApplicationListenerConfiguration.class)
.run((context) -> {
@ -593,7 +841,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@Test
@WithMetaInfPersistenceXmlResource
void whenLocalContainerEntityManagerFactoryBeanHasNoJpaVendorAdapterAutoConfigurationSucceeds() {
contextRunner()
this.contextRunner
.withUserConfiguration(
TestConfigurationWithLocalContainerEntityManagerFactoryBeanWithNoJpaVendorAdapter.class)
.run((context) -> {
@ -635,12 +883,12 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
// we're using an embedded database which means that HibernateProperties defaults
// hibernate.hbm2ddl.auto to create-drop, replacing the
// hibernate.hbm2ddl.auto=none that comes from generate-ddl being false.
contextRunner().run((context) -> assertThat(tablesFrom(context)).doesNotContain("CITY"));
this.contextRunner.run((context) -> assertThat(tablesFrom(context)).doesNotContain("CITY"));
}
@Test
void whenSpringJpaGenerateDdlIsTrueThenTableIsCreated() {
contextRunner().withPropertyValues("spring.jpa.generate-ddl=true")
this.contextRunner.withPropertyValues("spring.jpa.generate-ddl=true")
.run((context) -> assertThat(tablesFrom(context)).contains("CITY"));
}
@ -650,19 +898,19 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
// This test fails because we're using an embedded database which means that
// HibernateProperties defaults hibernate.hbm2ddl.auto to create-drop, replacing
// the hibernate.hbm2ddl.auto=none that comes from setting generate-ddl to false.
contextRunner().withPropertyValues("spring.jpa.generate-ddl=false")
this.contextRunner.withPropertyValues("spring.jpa.generate-ddl=false")
.run((context) -> assertThat(tablesFrom(context)).doesNotContain("CITY"));
}
@Test
void whenHbm2DdlAutoIsNoneThenTableIsNotCreated() {
contextRunner().withPropertyValues("spring.jpa.properties.hibernate.hbm2ddl.auto=none")
this.contextRunner.withPropertyValues("spring.jpa.properties.hibernate.hbm2ddl.auto=none")
.run((context) -> assertThat(tablesFrom(context)).doesNotContain("CITY"));
}
@Test
void whenSpringJpaHibernateDdlAutoIsNoneThenTableIsNotCreated() {
contextRunner().withPropertyValues("spring.jpa.hibernate.ddl-auto=none")
this.contextRunner.withPropertyValues("spring.jpa.hibernate.ddl-auto=none")
.run((context) -> assertThat(tablesFrom(context)).doesNotContain("CITY"));
}
@ -672,19 +920,19 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
// This test fails because when ddl-auto is set to none, we remove
// hibernate.hbm2ddl.auto from Hibernate properties. This then allows
// spring.jpa.generate-ddl to set it to create-drop
contextRunner().withPropertyValues("spring.jpa.generate-ddl=true", "spring.jpa.hibernate.ddl-auto=none")
this.contextRunner.withPropertyValues("spring.jpa.generate-ddl=true", "spring.jpa.hibernate.ddl-auto=none")
.run((context) -> assertThat(tablesFrom(context)).doesNotContain("CITY"));
}
@Test
void whenSpringJpaGenerateDdlIsTrueAndSpringJpaHibernateDdlAutoIsDropThenTableIsNotCreated() {
contextRunner().withPropertyValues("spring.jpa.generate-ddl=true", "spring.jpa.hibernate.ddl-auto=drop")
this.contextRunner.withPropertyValues("spring.jpa.generate-ddl=true", "spring.jpa.hibernate.ddl-auto=drop")
.run((context) -> assertThat(tablesFrom(context)).doesNotContain("CITY"));
}
@Test
void whenSpringJpaGenerateDdlIsTrueAndJakartaSchemaGenerationIsNoneThenTableIsNotCreated() {
contextRunner()
this.contextRunner
.withPropertyValues("spring.jpa.generate-ddl=true",
"spring.jpa.properties.jakarta.persistence.schema-generation.database.action=none")
.run((context) -> assertThat(tablesFrom(context)).doesNotContain("CITY"));
@ -692,7 +940,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@Test
void whenSpringJpaGenerateDdlIsTrueSpringJpaHibernateDdlAutoIsCreateAndJakartaSchemaGenerationIsNoneThenTableIsNotCreated() {
contextRunner()
this.contextRunner
.withPropertyValues("spring.jpa.generate-ddl=true", "spring.jpa.hibernate.ddl-auto=create",
"spring.jpa.properties.jakarta.persistence.schema-generation.database.action=none")
.run((context) -> assertThat(tablesFrom(context)).doesNotContain("CITY"));
@ -706,6 +954,219 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
return tables;
}
private Class<?>[] getManagedJavaTypes(EntityManager entityManager) {
Set<ManagedType<?>> managedTypes = entityManager.getMetamodel().getManagedTypes();
return managedTypes.stream().map(ManagedType::getJavaType).toArray(Class<?>[]::new);
}
@Configuration(proxyBeanMethods = false)
protected static class TestTwoDataSourcesConfiguration {
@Bean
DataSource firstDataSource() {
return createRandomDataSource();
}
@Bean
DataSource secondDataSource() {
return createRandomDataSource();
}
private DataSource createRandomDataSource() {
String url = "jdbc:h2:mem:init-" + UUID.randomUUID();
return DataSourceBuilder.create().url(url).build();
}
}
@Configuration(proxyBeanMethods = false)
static class TestTwoDataSourcesAndPrimaryConfiguration {
@Bean
@Primary
DataSource firstDataSource() {
return createRandomDataSource();
}
@Bean
DataSource secondDataSource() {
return createRandomDataSource();
}
private DataSource createRandomDataSource() {
String url = "jdbc:h2:mem:init-" + UUID.randomUUID();
return DataSourceBuilder.create().url(url).build();
}
}
@Configuration(proxyBeanMethods = false)
@TestAutoConfigurationPackage(City.class)
protected static class TestConfiguration {
}
@Configuration(proxyBeanMethods = false)
@TestAutoConfigurationPackage(City.class)
static class TestFilterConfiguration {
@Bean
OpenEntityManagerInViewFilter openEntityManagerInViewFilter() {
return new OpenEntityManagerInViewFilter();
}
}
@Configuration(proxyBeanMethods = false)
@TestAutoConfigurationPackage(City.class)
static class TestFilterRegistrationConfiguration {
@Bean
FilterRegistrationBean<OpenEntityManagerInViewFilter> openEntityManagerInViewFilterFilterRegistrationBean() {
return new FilterRegistrationBean<>();
}
}
@Configuration(proxyBeanMethods = false)
@TestAutoConfigurationPackage(City.class)
static class TestInterceptorManualConfiguration {
@Bean
OpenEntityManagerInViewInterceptor openEntityManagerInViewInterceptor() {
return new ManualOpenEntityManagerInViewInterceptor();
}
static class ManualOpenEntityManagerInViewInterceptor extends OpenEntityManagerInViewInterceptor {
}
}
@Configuration(proxyBeanMethods = false)
static class TestConfigurationWithEntityManagerFactoryBuilder extends TestConfiguration {
@Bean
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(EntityManagerFactoryBuilder builder,
DataSource dataSource) {
return builder.dataSource(dataSource).properties(Map.of("configured", "manually")).build();
}
}
@Configuration(proxyBeanMethods = false)
static class TestConfigurationWithLocalContainerEntityManagerFactoryBean extends TestConfiguration {
@Bean
LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, JpaVendorAdapter adapter) {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setJpaVendorAdapter(adapter);
factoryBean.setDataSource(dataSource);
factoryBean.setPersistenceUnitName("manually-configured");
Map<String, Object> properties = new HashMap<>();
properties.put("configured", "manually");
properties.put("hibernate.transaction.jta.platform", NoJtaPlatform.INSTANCE);
factoryBean.setJpaPropertyMap(properties);
return factoryBean;
}
}
@Configuration(proxyBeanMethods = false)
static class TestConfigurationWithEntityManagerFactory extends TestConfiguration {
@Bean
EntityManagerFactory entityManagerFactory(DataSource dataSource, JpaVendorAdapter adapter) {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setJpaVendorAdapter(adapter);
factoryBean.setDataSource(dataSource);
factoryBean.setPersistenceUnitName("manually-configured");
Map<String, Object> properties = new HashMap<>();
properties.put("configured", "manually");
properties.put("hibernate.transaction.jta.platform", NoJtaPlatform.INSTANCE);
factoryBean.setJpaPropertyMap(properties);
factoryBean.afterPropertiesSet();
return factoryBean.getObject();
}
@Bean
PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
}
@Configuration(proxyBeanMethods = false)
@TestAutoConfigurationPackage(City.class)
static class TestConfigurationWithTransactionManager {
@Bean
JpaTransactionManager testTransactionManager() {
return new CustomJpaTransactionManager();
}
}
@Configuration(proxyBeanMethods = false)
@TestAutoConfigurationPackage(Country.class)
static class AutoConfigurePackageForCountry {
}
@Configuration(proxyBeanMethods = false)
@TestAutoConfigurationPackage(HibernateJpaAutoConfigurationTests.class)
static class TestConfigurationWithCustomPersistenceUnitManager {
private final DataSource dataSource;
TestConfigurationWithCustomPersistenceUnitManager(DataSource dataSource) {
this.dataSource = dataSource;
}
@Bean
PersistenceUnitManager persistenceUnitManager() {
DefaultPersistenceUnitManager persistenceUnitManager = new DefaultPersistenceUnitManager();
persistenceUnitManager.setDefaultDataSource(this.dataSource);
persistenceUnitManager.setPackagesToScan(City.class.getPackage().getName());
return persistenceUnitManager;
}
}
@Configuration(proxyBeanMethods = false)
@TestAutoConfigurationPackage(HibernateJpaAutoConfigurationTests.class)
static class TestConfigurationWithCustomPersistenceUnitPostProcessors {
@Bean
EntityManagerFactoryBuilderCustomizer entityManagerFactoryBuilderCustomizer() {
return (builder) -> builder.setPersistenceUnitPostProcessors(
(pui) -> pui.addManagedClassName("customized.attribute.converter.class.name"));
}
}
static class CustomJpaTransactionManager extends JpaTransactionManager {
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@WithResource(name = "META-INF/persistence.xml",
content = """
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence https://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="manually-configured">
<class>org.springframework.boot.jpa.autoconfigure.test.city.City</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
</persistence-unit>
</persistence>
""")
protected @interface WithMetaInfPersistenceXmlResource {
}
@Configuration(proxyBeanMethods = false)
@TestAutoConfigurationPackage(City.class)
@DependsOnDatabaseInitialization

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.jpa.hibernate.metrics.autoconfigure;
package org.springframework.boot.hibernate.autoconfigure;
import java.util.Map;
import java.util.function.Function;
@ -37,7 +37,6 @@ import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration;
import org.springframework.boot.jdbc.autoconfigure.DataSourceInitializationAutoConfiguration;
import org.springframework.boot.jpa.EntityManagerFactoryBuilder;
import org.springframework.boot.jpa.autoconfigure.EntityManagerFactoryBuilderCustomizer;
import org.springframework.boot.jpa.autoconfigure.hibernate.HibernateJpaAutoConfiguration;
import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.jpa.autoconfigure.hibernate;
package org.springframework.boot.hibernate.autoconfigure;
import java.util.Map;
import java.util.function.Consumer;
@ -30,8 +30,8 @@ import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.hibernate.SpringImplicitNamingStrategy;
import org.springframework.boot.jpa.autoconfigure.JpaProperties;
import org.springframework.boot.jpa.hibernate.SpringImplicitNamingStrategy;
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.context.runner.ContextConsumer;

View File

@ -17,7 +17,6 @@
plugins {
id "java-library"
id "org.springframework.boot.auto-configuration"
id "org.springframework.boot.configuration-properties"
id "org.springframework.boot.deployed"
id "org.springframework.boot.optional-dependencies"
@ -29,31 +28,14 @@ dependencies {
api(project(":spring-boot-project:spring-boot-jdbc"))
api(project(":spring-boot-project:spring-boot-tx"))
api("jakarta.persistence:jakarta.persistence-api")
api("org.hibernate.orm:hibernate-core")
api("org.springframework:spring-orm")
optional(project(":spring-boot-project:spring-boot-autoconfigure"))
optional(project(":spring-boot-project:spring-boot-metrics"))
optional("jakarta.servlet:jakarta.servlet-api")
optional("org.hibernate.orm:hibernate-micrometer")
optional("org.springframework:spring-webmvc")
testImplementation(project(":spring-boot-project:spring-boot-flyway"))
testImplementation(project(":spring-boot-project:spring-boot-liquibase"))
testImplementation(project(":spring-boot-project:spring-boot-test"))
testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support"))
testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure")))
testImplementation("com.zaxxer:HikariCP")
testImplementation("javax.cache:cache-api")
testImplementation("org.ehcache:ehcache") {
artifact {
classifier = 'jakarta'
}
}
testImplementation("org.hibernate.orm:hibernate-envers")
testImplementation("org.hibernate.orm:hibernate-jcache")
testImplementation("org.springframework:spring-context-support")
testRuntimeOnly("ch.qos.logback:logback-classic")
testRuntimeOnly("com.h2database:h2")
}

View File

@ -1,20 +0,0 @@
/*
* Copyright 2012-present 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
*
* https://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.
*/
/**
* Auto-configuration for Hibernate metrics.
*/
package org.springframework.boot.jpa.hibernate.metrics.autoconfigure;

View File

@ -1,79 +1,11 @@
{
"groups": [],
"properties": [
{
"name": "spring.jpa.hibernate.use-new-id-generator-mappings",
"type": "java.lang.Boolean",
"description": "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\".",
"deprecation": {
"level": "error",
"reason": "Hibernate no longer supports disabling the use of new ID generator mappings."
}
},
{
"name": "spring.jpa.open-in-view",
"defaultValue": true
}
],
"hints": [
{
"name": "spring.jpa.hibernate.ddl-auto",
"values": [
{
"value": "create",
"description": "Create the schema and destroy previous data."
},
{
"value": "create-drop",
"description": "Create and then destroy the schema at the end of the session."
},
{
"value": "create-only",
"description": "Create the schema."
},
{
"value": "drop",
"description": "Drop the schema."
},
{
"value": "none",
"description": "Disable DDL handling."
},
{
"value": "truncate",
"description": "Truncate the tables in the schema."
},
{
"value": "update",
"description": "Update the schema if necessary."
},
{
"value": "validate",
"description": "Validate the schema, make no changes to the database."
}
]
},
{
"name": "spring.jpa.hibernate.naming.implicit-strategy",
"providers": [
{
"name": "class-reference",
"parameters": {
"target": "org.hibernate.boot.model.naming.ImplicitNamingStrategy"
}
}
]
},
{
"name": "spring.jpa.hibernate.naming.physical-strategy",
"providers": [
{
"name": "class-reference",
"parameters": {
"target": "org.hibernate.boot.model.naming.PhysicalNamingStrategy"
}
}
]
}
]
}

View File

@ -1,2 +0,0 @@
org.springframework.boot.jpa.autoconfigure.hibernate.HibernateJpaAutoConfiguration
org.springframework.boot.jpa.hibernate.metrics.autoconfigure.HibernateMetricsAutoConfiguration

View File

@ -1,528 +0,0 @@
/*
* Copyright 2012-present 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
*
* https://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.jpa.autoconfigure;
import java.io.File;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import javax.sql.DataSource;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.metamodel.ManagedType;
import jakarta.persistence.spi.PersistenceUnitInfo;
import org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration;
import org.springframework.boot.jdbc.autoconfigure.DataSourceInitializationAutoConfiguration;
import org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.jpa.EntityManagerFactoryBuilder;
import org.springframework.boot.jpa.autoconfigure.test.city.City;
import org.springframework.boot.jpa.autoconfigure.test.country.Country;
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.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.testsupport.BuildOutput;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration;
import org.springframework.boot.transaction.autoconfigure.TransactionManagerCustomizationAutoConfiguration;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager;
import org.springframework.orm.jpa.persistenceunit.ManagedClassNameFilter;
import org.springframework.orm.jpa.persistenceunit.PersistenceManagedTypes;
import org.springframework.orm.jpa.persistenceunit.PersistenceUnitManager;
import org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter;
import org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionManager;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Base for JPA tests and tests for {@link JpaBaseConfiguration}.
*
* @author Phillip Webb
* @author Dave Syer
* @author Stephane Nicoll
* @author Yanming Zhou
*/
public abstract class AbstractJpaAutoConfigurationTests {
private final Class<?> autoConfiguredClass;
private final ApplicationContextRunner contextRunner;
protected AbstractJpaAutoConfigurationTests(Class<?> autoConfiguredClass) {
this.autoConfiguredClass = autoConfiguredClass;
this.contextRunner = new ApplicationContextRunner()
.withPropertyValues("spring.datasource.generate-unique-name=true",
"spring.jta.log-dir=" + new File(new BuildOutput(getClass()).getRootLocation(), "transaction-logs"))
.withUserConfiguration(TestConfiguration.class)
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class,
TransactionAutoConfiguration.class, TransactionManagerCustomizationAutoConfiguration.class,
DataSourceInitializationAutoConfiguration.class, autoConfiguredClass));
}
protected ApplicationContextRunner contextRunner() {
return this.contextRunner;
}
@Test
void notConfiguredIfDataSourceIsNotAvailable() {
new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(this.autoConfiguredClass))
.run(assertJpaIsNotAutoConfigured());
}
@Test
void notConfiguredIfNoSingleDataSourceCandidateIsAvailable() {
new ApplicationContextRunner().withUserConfiguration(TestTwoDataSourcesConfiguration.class)
.withConfiguration(AutoConfigurations.of(this.autoConfiguredClass))
.run(assertJpaIsNotAutoConfigured());
}
protected ContextConsumer<AssertableApplicationContext> assertJpaIsNotAutoConfigured() {
return (context) -> {
assertThat(context).hasNotFailed();
assertThat(context).hasSingleBean(JpaProperties.class);
assertThat(context).doesNotHaveBean(TransactionManager.class);
assertThat(context).doesNotHaveBean(EntityManagerFactory.class);
};
}
@Test
void configuredWithAutoConfiguredDataSource() {
this.contextRunner.run((context) -> {
assertThat(context).hasSingleBean(DataSource.class);
assertThat(context).hasSingleBean(JpaTransactionManager.class);
assertThat(context).hasSingleBean(EntityManagerFactory.class);
assertThat(context).hasSingleBean(PersistenceManagedTypes.class);
});
}
@Test
void configuredWithSingleCandidateDataSource() {
this.contextRunner.withUserConfiguration(TestTwoDataSourcesAndPrimaryConfiguration.class).run((context) -> {
assertThat(context).getBeans(DataSource.class).hasSize(2);
assertThat(context).hasSingleBean(JpaTransactionManager.class);
assertThat(context).hasSingleBean(EntityManagerFactory.class);
assertThat(context).hasSingleBean(PersistenceManagedTypes.class);
});
}
@Test
void jpaTransactionManagerTakesPrecedenceOverSimpleDataSourceOne() {
this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceTransactionManagerAutoConfiguration.class))
.run((context) -> {
assertThat(context).hasSingleBean(DataSource.class);
assertThat(context).hasSingleBean(JpaTransactionManager.class);
assertThat(context).getBean("transactionManager").isInstanceOf(JpaTransactionManager.class);
});
}
@Test
void openEntityManagerInViewInterceptorIsCreated() {
new WebApplicationContextRunner().withPropertyValues("spring.datasource.generate-unique-name=true")
.withUserConfiguration(TestConfiguration.class)
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class,
TransactionAutoConfiguration.class, this.autoConfiguredClass))
.run((context) -> assertThat(context).hasSingleBean(OpenEntityManagerInViewInterceptor.class));
}
@Test
void openEntityManagerInViewInterceptorIsNotRegisteredWhenFilterPresent() {
new WebApplicationContextRunner().withPropertyValues("spring.datasource.generate-unique-name=true")
.withUserConfiguration(TestFilterConfiguration.class)
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class,
TransactionAutoConfiguration.class, this.autoConfiguredClass))
.run((context) -> assertThat(context).doesNotHaveBean(OpenEntityManagerInViewInterceptor.class));
}
@Test
void openEntityManagerInViewInterceptorIsNotRegisteredWhenFilterRegistrationPresent() {
new WebApplicationContextRunner().withPropertyValues("spring.datasource.generate-unique-name=true")
.withUserConfiguration(TestFilterRegistrationConfiguration.class)
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class,
TransactionAutoConfiguration.class, this.autoConfiguredClass))
.run((context) -> assertThat(context).doesNotHaveBean(OpenEntityManagerInViewInterceptor.class));
}
@Test
void openEntityManagerInViewInterceptorAutoConfigurationBacksOffWhenManuallyRegistered() {
new WebApplicationContextRunner().withPropertyValues("spring.datasource.generate-unique-name=true")
.withUserConfiguration(TestInterceptorManualConfiguration.class)
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class,
TransactionAutoConfiguration.class, this.autoConfiguredClass))
.run((context) -> assertThat(context).getBean(OpenEntityManagerInViewInterceptor.class)
.isExactlyInstanceOf(
TestInterceptorManualConfiguration.ManualOpenEntityManagerInViewInterceptor.class));
}
@Test
void openEntityManagerInViewInterceptorIsNotRegisteredWhenExplicitlyOff() {
new WebApplicationContextRunner()
.withPropertyValues("spring.datasource.generate-unique-name=true", "spring.jpa.open-in-view=false")
.withUserConfiguration(TestConfiguration.class)
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class,
TransactionAutoConfiguration.class, this.autoConfiguredClass))
.run((context) -> assertThat(context).doesNotHaveBean(OpenEntityManagerInViewInterceptor.class));
}
@Test
void customJpaProperties() {
this.contextRunner
.withPropertyValues("spring.jpa.properties.a:b", "spring.jpa.properties.a.b:c", "spring.jpa.properties.c:d")
.run((context) -> {
LocalContainerEntityManagerFactoryBean bean = context
.getBean(LocalContainerEntityManagerFactoryBean.class);
Map<String, Object> map = bean.getJpaPropertyMap();
assertThat(map).containsEntry("a", "b");
assertThat(map).containsEntry("c", "d");
assertThat(map).containsEntry("a.b", "c");
});
}
@Test
@WithMetaInfPersistenceXmlResource
void usesManuallyDefinedLocalContainerEntityManagerFactoryBeanUsingBuilder() {
this.contextRunner.withPropertyValues("spring.jpa.properties.a=b")
.withUserConfiguration(TestConfigurationWithEntityManagerFactoryBuilder.class)
.run((context) -> {
LocalContainerEntityManagerFactoryBean factoryBean = context
.getBean(LocalContainerEntityManagerFactoryBean.class);
Map<String, Object> map = factoryBean.getJpaPropertyMap();
assertThat(map).containsEntry("configured", "manually").containsEntry("a", "b");
});
}
@Test
@WithMetaInfPersistenceXmlResource
void usesManuallyDefinedLocalContainerEntityManagerFactoryBeanIfAvailable() {
this.contextRunner.withUserConfiguration(TestConfigurationWithLocalContainerEntityManagerFactoryBean.class)
.run((context) -> {
LocalContainerEntityManagerFactoryBean factoryBean = context
.getBean(LocalContainerEntityManagerFactoryBean.class);
Map<String, Object> map = factoryBean.getJpaPropertyMap();
assertThat(map).containsEntry("configured", "manually");
});
}
@Test
@WithMetaInfPersistenceXmlResource
void usesManuallyDefinedEntityManagerFactoryIfAvailable() {
this.contextRunner.withUserConfiguration(TestConfigurationWithLocalContainerEntityManagerFactoryBean.class)
.run((context) -> {
EntityManagerFactory factoryBean = context.getBean(EntityManagerFactory.class);
Map<String, Object> map = factoryBean.getProperties();
assertThat(map).containsEntry("configured", "manually");
});
}
@Test
void usesManuallyDefinedTransactionManagerBeanIfAvailable() {
this.contextRunner.withUserConfiguration(TestConfigurationWithTransactionManager.class).run((context) -> {
assertThat(context).hasSingleBean(TransactionManager.class);
TransactionManager txManager = context.getBean(TransactionManager.class);
assertThat(txManager).isInstanceOf(CustomJpaTransactionManager.class);
});
}
@Test
void defaultPersistenceManagedTypes() {
this.contextRunner.run((context) -> {
assertThat(context).hasSingleBean(PersistenceManagedTypes.class);
EntityManager entityManager = context.getBean(EntityManagerFactory.class).createEntityManager();
assertThat(getManagedJavaTypes(entityManager)).contains(City.class).doesNotContain(Country.class);
});
}
@Test
void customPersistenceManagedTypes() {
this.contextRunner
.withBean(PersistenceManagedTypes.class, () -> PersistenceManagedTypes.of(Country.class.getName()))
.run((context) -> {
assertThat(context).hasSingleBean(PersistenceManagedTypes.class);
EntityManager entityManager = context.getBean(EntityManagerFactory.class).createEntityManager();
assertThat(getManagedJavaTypes(entityManager)).contains(Country.class).doesNotContain(City.class);
});
}
@Test
void customPersistenceUnitManager() {
this.contextRunner.withUserConfiguration(TestConfigurationWithCustomPersistenceUnitManager.class)
.run((context) -> {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = context
.getBean(LocalContainerEntityManagerFactoryBean.class);
assertThat(entityManagerFactoryBean).hasFieldOrPropertyWithValue("persistenceUnitManager",
context.getBean(PersistenceUnitManager.class));
});
}
@Test
void customPersistenceUnitPostProcessors() {
this.contextRunner.withUserConfiguration(TestConfigurationWithCustomPersistenceUnitPostProcessors.class)
.run((context) -> {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = context
.getBean(LocalContainerEntityManagerFactoryBean.class);
PersistenceUnitInfo persistenceUnitInfo = entityManagerFactoryBean.getPersistenceUnitInfo();
assertThat(persistenceUnitInfo).isNotNull();
assertThat(persistenceUnitInfo.getManagedClassNames())
.contains("customized.attribute.converter.class.name");
});
}
@Test
void customManagedClassNameFilter() {
this.contextRunner.withBean(ManagedClassNameFilter.class, () -> (s) -> !s.endsWith("City"))
.withUserConfiguration(AutoConfigurePackageForCountry.class)
.run((context) -> {
EntityManager entityManager = context.getBean(EntityManagerFactory.class).createEntityManager();
assertThat(getManagedJavaTypes(entityManager)).contains(Country.class).doesNotContain(City.class);
});
}
private Class<?>[] getManagedJavaTypes(EntityManager entityManager) {
Set<ManagedType<?>> managedTypes = entityManager.getMetamodel().getManagedTypes();
return managedTypes.stream().map(ManagedType::getJavaType).toArray(Class<?>[]::new);
}
@Configuration(proxyBeanMethods = false)
protected static class TestTwoDataSourcesConfiguration {
@Bean
DataSource firstDataSource() {
return createRandomDataSource();
}
@Bean
DataSource secondDataSource() {
return createRandomDataSource();
}
private DataSource createRandomDataSource() {
String url = "jdbc:h2:mem:init-" + UUID.randomUUID();
return DataSourceBuilder.create().url(url).build();
}
}
@Configuration(proxyBeanMethods = false)
static class TestTwoDataSourcesAndPrimaryConfiguration {
@Bean
@Primary
DataSource firstDataSource() {
return createRandomDataSource();
}
@Bean
DataSource secondDataSource() {
return createRandomDataSource();
}
private DataSource createRandomDataSource() {
String url = "jdbc:h2:mem:init-" + UUID.randomUUID();
return DataSourceBuilder.create().url(url).build();
}
}
@Configuration(proxyBeanMethods = false)
@TestAutoConfigurationPackage(City.class)
protected static class TestConfiguration {
}
@Configuration(proxyBeanMethods = false)
@TestAutoConfigurationPackage(City.class)
static class TestFilterConfiguration {
@Bean
OpenEntityManagerInViewFilter openEntityManagerInViewFilter() {
return new OpenEntityManagerInViewFilter();
}
}
@Configuration(proxyBeanMethods = false)
@TestAutoConfigurationPackage(City.class)
static class TestFilterRegistrationConfiguration {
@Bean
FilterRegistrationBean<OpenEntityManagerInViewFilter> openEntityManagerInViewFilterFilterRegistrationBean() {
return new FilterRegistrationBean<>();
}
}
@Configuration(proxyBeanMethods = false)
@TestAutoConfigurationPackage(City.class)
static class TestInterceptorManualConfiguration {
@Bean
OpenEntityManagerInViewInterceptor openEntityManagerInViewInterceptor() {
return new ManualOpenEntityManagerInViewInterceptor();
}
static class ManualOpenEntityManagerInViewInterceptor extends OpenEntityManagerInViewInterceptor {
}
}
@Configuration(proxyBeanMethods = false)
static class TestConfigurationWithEntityManagerFactoryBuilder extends TestConfiguration {
@Bean
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(EntityManagerFactoryBuilder builder,
DataSource dataSource) {
return builder.dataSource(dataSource).properties(Map.of("configured", "manually")).build();
}
}
@Configuration(proxyBeanMethods = false)
static class TestConfigurationWithLocalContainerEntityManagerFactoryBean extends TestConfiguration {
@Bean
LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, JpaVendorAdapter adapter) {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setJpaVendorAdapter(adapter);
factoryBean.setDataSource(dataSource);
factoryBean.setPersistenceUnitName("manually-configured");
Map<String, Object> properties = new HashMap<>();
properties.put("configured", "manually");
properties.put("hibernate.transaction.jta.platform", NoJtaPlatform.INSTANCE);
factoryBean.setJpaPropertyMap(properties);
return factoryBean;
}
}
@Configuration(proxyBeanMethods = false)
static class TestConfigurationWithEntityManagerFactory extends TestConfiguration {
@Bean
EntityManagerFactory entityManagerFactory(DataSource dataSource, JpaVendorAdapter adapter) {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setJpaVendorAdapter(adapter);
factoryBean.setDataSource(dataSource);
factoryBean.setPersistenceUnitName("manually-configured");
Map<String, Object> properties = new HashMap<>();
properties.put("configured", "manually");
properties.put("hibernate.transaction.jta.platform", NoJtaPlatform.INSTANCE);
factoryBean.setJpaPropertyMap(properties);
factoryBean.afterPropertiesSet();
return factoryBean.getObject();
}
@Bean
PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
}
@Configuration(proxyBeanMethods = false)
@TestAutoConfigurationPackage(City.class)
static class TestConfigurationWithTransactionManager {
@Bean
TransactionManager testTransactionManager() {
return new CustomJpaTransactionManager();
}
}
@Configuration(proxyBeanMethods = false)
@TestAutoConfigurationPackage(Country.class)
static class AutoConfigurePackageForCountry {
}
@Configuration(proxyBeanMethods = false)
@TestAutoConfigurationPackage(AbstractJpaAutoConfigurationTests.class)
static class TestConfigurationWithCustomPersistenceUnitManager {
private final DataSource dataSource;
TestConfigurationWithCustomPersistenceUnitManager(DataSource dataSource) {
this.dataSource = dataSource;
}
@Bean
PersistenceUnitManager persistenceUnitManager() {
DefaultPersistenceUnitManager persistenceUnitManager = new DefaultPersistenceUnitManager();
persistenceUnitManager.setDefaultDataSource(this.dataSource);
persistenceUnitManager.setPackagesToScan(City.class.getPackage().getName());
return persistenceUnitManager;
}
}
@Configuration(proxyBeanMethods = false)
@TestAutoConfigurationPackage(AbstractJpaAutoConfigurationTests.class)
static class TestConfigurationWithCustomPersistenceUnitPostProcessors {
@Bean
EntityManagerFactoryBuilderCustomizer entityManagerFactoryBuilderCustomizer() {
return (builder) -> builder.setPersistenceUnitPostProcessors(
(pui) -> pui.addManagedClassName("customized.attribute.converter.class.name"));
}
}
static class CustomJpaTransactionManager extends JpaTransactionManager {
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@WithResource(name = "META-INF/persistence.xml",
content = """
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence https://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="manually-configured">
<class>org.springframework.boot.jpa.autoconfigure.test.city.City</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
</persistence-unit>
</persistence>
""")
protected @interface WithMetaInfPersistenceXmlResource {
}
}

View File

@ -35,7 +35,7 @@ dependencies {
optional(project(":spring-boot-project:spring-boot-actuator-autoconfigure"))
optional(project(":spring-boot-project:spring-boot-autoconfigure"))
optional(project(":spring-boot-project:spring-boot-jdbc"))
optional(project(":spring-boot-project:spring-boot-jpa"))
optional(project(":spring-boot-project:spring-boot-hibernate"))
testImplementation(project(":spring-boot-project:spring-boot-flyway"))
testImplementation(project(":spring-boot-project:spring-boot-liquibase"))

View File

@ -54,7 +54,7 @@ import org.springframework.transaction.PlatformTransactionManager;
* @since 4.0.0
*/
@AutoConfiguration(afterName = { "org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration",
"org.springframework.boot.jpa.autoconfigure.hibernate.HibernateJpaAutoConfiguration" })
"org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration" })
@ConditionalOnClass({ Scheduler.class, SchedulerFactoryBean.class, PlatformTransactionManager.class })
@EnableConfigurationProperties(QuartzProperties.class)
public class QuartzAutoConfiguration {

View File

@ -54,9 +54,9 @@ dependencies {
optional("org.springframework.security:spring-security-messaging")
optional("org.springframework.security:spring-security-rsocket")
testImplementation(project(":spring-boot-project:spring-boot-hibernate"))
testImplementation(project(":spring-boot-project:spring-boot-http-converter"))
testImplementation(project(":spring-boot-project:spring-boot-jackson"))
testImplementation(project(":spring-boot-project:spring-boot-jpa"))
testImplementation(project(":spring-boot-project:spring-boot-restclient"))
testImplementation(project(":spring-boot-project:spring-boot-rsocket"))
testImplementation(project(":spring-boot-project:spring-boot-test"))

View File

@ -19,9 +19,9 @@ package org.springframework.boot.security.autoconfigure.jpa;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration;
import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration;
import org.springframework.boot.jdbc.autoconfigure.EmbeddedDataSourceConfiguration;
import org.springframework.boot.jpa.autoconfigure.hibernate.HibernateJpaAutoConfiguration;
import org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration;
import org.springframework.boot.test.context.SpringBootContextLoader;
import org.springframework.context.annotation.Import;

View File

@ -34,8 +34,8 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConfigurationPropertiesBinding;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.convert.ApplicationConversionService;
import org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration;
import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration;
import org.springframework.boot.jpa.autoconfigure.hibernate.HibernateJpaAutoConfiguration;
import org.springframework.boot.security.autoconfigure.jpa.City;
import org.springframework.boot.servlet.filter.OrderedFilter;
import org.springframework.boot.test.context.FilteredClassLoader;

View File

@ -30,7 +30,7 @@ import org.springframework.context.annotation.Bean;
* @since 1.4.0
* @see AutoConfigureTestEntityManager
*/
@AutoConfiguration(afterName = "org.springframework.boot.jpa.autoconfigure.hibernate.HibernateJpaAutoConfiguration")
@AutoConfiguration(afterName = "org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration")
@ConditionalOnClass({ EntityManagerFactory.class })
public class TestEntityManagerAutoConfiguration {

View File

@ -1,6 +1,6 @@
# AutoConfigureDataJpa auto-configuration imports
org.springframework.boot.data.jpa.autoconfigure.JpaRepositoriesAutoConfiguration
org.springframework.boot.jpa.autoconfigure.hibernate.HibernateJpaAutoConfiguration
org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration
org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration
org.springframework.boot.jdbc.autoconfigure.DataSourceInitializationAutoConfiguration
org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration

View File

@ -18,13 +18,13 @@ plugins {
id "java"
}
description = "Spring Boot JPA smoke test"
description = "Spring Boot Hibernate smoke test"
dependencies {
implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-freemarker"))
implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web"))
implementation(project(":spring-boot-project:spring-boot-jdbc"))
implementation(project(":spring-boot-project:spring-boot-jpa"))
implementation(project(":spring-boot-project:spring-boot-hibernate"))
implementation("jakarta.xml.bind:jakarta.xml.bind-api")
runtimeOnly("com.h2database:h2")

View File

@ -86,4 +86,5 @@
<suppress files="SpringBootBanner\.java" checks="SpringLeadingWhitespace" />
<suppress files="LoadTimeWeaverAwareConsumerContainers\.java" checks="InterfaceIsType" />
<suppress files="ConfigurationPropertyCaching\.java" checks="SpringJavadoc" message="\@since"/>
<suppress files=".*MetricsAutoConfiguration\.java" checks="ImportControl" message=".micrometer"/>
</suppressions>