Merge branch '3.4.x'
Closes gh-44626
This commit is contained in:
commit
0a84ebf9f1
@ -16,8 +16,8 @@
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.metrics.orm.jpa;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
@ -194,9 +194,10 @@ class HibernateMetricsAutoConfigurationTests {
|
||||
}
|
||||
|
||||
private LocalContainerEntityManagerFactoryBean createSessionFactory(DataSource ds) {
|
||||
Map<String, String> jpaProperties = new HashMap<>();
|
||||
jpaProperties.put("hibernate.generate_statistics", "true");
|
||||
return new EntityManagerFactoryBuilder(new HibernateJpaVendorAdapter(), jpaProperties, null).dataSource(ds)
|
||||
Function<DataSource, Map<String, ?>> jpaPropertiesFactory = (dataSource) -> Map
|
||||
.of("hibernate.generate_statistics", "true");
|
||||
return new EntityManagerFactoryBuilder(new HibernateJpaVendorAdapter(), jpaPropertiesFactory, null)
|
||||
.dataSource(ds)
|
||||
.packages(PACKAGE_CLASSES)
|
||||
.build();
|
||||
}
|
||||
|
@ -145,8 +145,8 @@ class HibernateJpaConfiguration extends JpaBaseConfiguration {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, Object> getVendorProperties() {
|
||||
Supplier<String> defaultDdlMode = () -> this.defaultDdlAutoProvider.getDefaultDdlAuto(getDataSource());
|
||||
protected Map<String, Object> getVendorProperties(DataSource dataSource) {
|
||||
Supplier<String> defaultDdlMode = () -> this.defaultDdlAutoProvider.getDefaultDdlAuto(dataSource);
|
||||
return new LinkedHashMap<>(this.hibernateProperties.determineHibernateProperties(
|
||||
getProperties().getProperties(), new HibernateSettings().ddlAuto(defaultDdlMode)
|
||||
.hibernatePropertiesCustomizers(this.hibernatePropertiesCustomizers)));
|
||||
|
@ -120,15 +120,15 @@ public abstract class JpaBaseConfiguration {
|
||||
public EntityManagerFactoryBuilder entityManagerFactoryBuilder(JpaVendorAdapter jpaVendorAdapter,
|
||||
ObjectProvider<PersistenceUnitManager> persistenceUnitManager,
|
||||
ObjectProvider<EntityManagerFactoryBuilderCustomizer> customizers) {
|
||||
EntityManagerFactoryBuilder builder = new EntityManagerFactoryBuilder(jpaVendorAdapter, buildJpaProperties(),
|
||||
persistenceUnitManager.getIfAvailable());
|
||||
EntityManagerFactoryBuilder builder = new EntityManagerFactoryBuilder(jpaVendorAdapter,
|
||||
this::buildJpaProperties, persistenceUnitManager.getIfAvailable());
|
||||
customizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
|
||||
return builder;
|
||||
}
|
||||
|
||||
private Map<String, ?> buildJpaProperties() {
|
||||
private Map<String, ?> buildJpaProperties(DataSource dataSource) {
|
||||
Map<String, Object> properties = new HashMap<>(this.properties.getProperties());
|
||||
Map<String, Object> vendorProperties = getVendorProperties();
|
||||
Map<String, Object> vendorProperties = getVendorProperties(dataSource);
|
||||
customizeVendorProperties(vendorProperties);
|
||||
properties.putAll(vendorProperties);
|
||||
return properties;
|
||||
@ -148,7 +148,24 @@ public abstract class JpaBaseConfiguration {
|
||||
|
||||
protected abstract AbstractJpaVendorAdapter createJpaVendorAdapter();
|
||||
|
||||
protected abstract Map<String, Object> getVendorProperties();
|
||||
/**
|
||||
* Return the vendor-specific properties for the given {@link DataSource}.
|
||||
* @param dataSource the data source
|
||||
* @return the vendor properties
|
||||
* @since 3.4.4
|
||||
*/
|
||||
protected abstract Map<String, Object> getVendorProperties(DataSource dataSource);
|
||||
|
||||
/**
|
||||
* Return the vendor-specific properties.
|
||||
* @return the vendor properties
|
||||
* @deprecated since 3.4.4 for removal in 3.6.0 in favor of
|
||||
* {@link #getVendorProperties(DataSource)}
|
||||
*/
|
||||
@Deprecated(since = "3.4.4", forRemoval = true)
|
||||
protected Map<String, Object> getVendorProperties() {
|
||||
return getVendorProperties(getDataSource());
|
||||
}
|
||||
|
||||
/**
|
||||
* Customize vendor properties before they are used. Allows for post-processing (for
|
||||
|
@ -65,11 +65,14 @@ import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration.Fly
|
||||
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration.OracleFlywayConfigurationCustomizer;
|
||||
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration.PostgresqlFlywayConfigurationCustomizer;
|
||||
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration.SqlServerFlywayConfigurationCustomizer;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
|
||||
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.jdbc.DataSourceBuilder;
|
||||
import org.springframework.boot.jdbc.EmbeddedDatabaseConnection;
|
||||
import org.springframework.boot.jdbc.SchemaManagement;
|
||||
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
@ -489,6 +492,36 @@ class FlywayAutoConfigurationTests {
|
||||
.run((context) -> assertThat(context).hasNotFailed());
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMetaInfPersistenceXmlResource
|
||||
void jpaApplyDdl() {
|
||||
this.contextRunner
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class))
|
||||
.run((context) -> {
|
||||
Map<String, Object> jpaProperties = context.getBean(LocalContainerEntityManagerFactoryBean.class)
|
||||
.getJpaPropertyMap();
|
||||
assertThat(jpaProperties).doesNotContainKey("hibernate.hbm2ddl.auto");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMetaInfPersistenceXmlResource
|
||||
void jpaAndMultipleDataSourcesApplyDdl() {
|
||||
this.contextRunner.withConfiguration(AutoConfigurations.of(HibernateJpaAutoConfiguration.class))
|
||||
.withUserConfiguration(JpaWithMultipleDataSourcesConfiguration.class)
|
||||
.run((context) -> {
|
||||
LocalContainerEntityManagerFactoryBean normalEntityManagerFactoryBean = context
|
||||
.getBean("&normalEntityManagerFactory", LocalContainerEntityManagerFactoryBean.class);
|
||||
assertThat(normalEntityManagerFactoryBean.getJpaPropertyMap()).containsEntry("configured", "normal")
|
||||
.containsEntry("hibernate.hbm2ddl.auto", "create-drop");
|
||||
LocalContainerEntityManagerFactoryBean flywayEntityManagerFactoryBean = context
|
||||
.getBean("&flywayEntityManagerFactory", LocalContainerEntityManagerFactoryBean.class);
|
||||
assertThat(flywayEntityManagerFactoryBean.getJpaPropertyMap()).containsEntry("configured", "flyway")
|
||||
.doesNotContainKey("hibernate.hbm2ddl.auto");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void customFlywayWithJdbc() {
|
||||
this.contextRunner
|
||||
@ -962,6 +995,13 @@ class FlywayAutoConfigurationTests {
|
||||
};
|
||||
}
|
||||
|
||||
private static Map<String, ?> configureJpaProperties() {
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
properties.put("configured", "manually");
|
||||
properties.put("hibernate.transaction.jta.platform", NoJtaPlatform.INSTANCE);
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class FlywayDataSourceConfiguration {
|
||||
|
||||
@ -1057,10 +1097,8 @@ class FlywayAutoConfigurationTests {
|
||||
|
||||
@Bean
|
||||
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(DataSource dataSource) {
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
properties.put("configured", "manually");
|
||||
properties.put("hibernate.transaction.jta.platform", NoJtaPlatform.INSTANCE);
|
||||
return new EntityManagerFactoryBuilder(new HibernateJpaVendorAdapter(), properties, null)
|
||||
return new EntityManagerFactoryBuilder(new HibernateJpaVendorAdapter(), (ds) -> configureJpaProperties(),
|
||||
null)
|
||||
.dataSource(dataSource)
|
||||
.build();
|
||||
}
|
||||
@ -1083,16 +1121,54 @@ class FlywayAutoConfigurationTests {
|
||||
|
||||
@Bean
|
||||
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
properties.put("configured", "manually");
|
||||
properties.put("hibernate.transaction.jta.platform", NoJtaPlatform.INSTANCE);
|
||||
return new EntityManagerFactoryBuilder(new HibernateJpaVendorAdapter(), properties, null)
|
||||
return new EntityManagerFactoryBuilder(new HibernateJpaVendorAdapter(),
|
||||
(datasource) -> configureJpaProperties(), null)
|
||||
.dataSource(this.dataSource)
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class JpaWithMultipleDataSourcesConfiguration {
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
DataSource normalDataSource() {
|
||||
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseConnection.HSQLDB.getType())
|
||||
.generateUniqueName(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
LocalContainerEntityManagerFactoryBean normalEntityManagerFactory(EntityManagerFactoryBuilder builder,
|
||||
DataSource normalDataSource) {
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
properties.put("configured", "normal");
|
||||
properties.put("hibernate.transaction.jta.platform", NoJtaPlatform.INSTANCE);
|
||||
return builder.dataSource(normalDataSource).properties(properties).build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@FlywayDataSource
|
||||
DataSource flywayDataSource() {
|
||||
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseConnection.HSQLDB.getType())
|
||||
.generateUniqueName(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
LocalContainerEntityManagerFactoryBean flywayEntityManagerFactory(EntityManagerFactoryBuilder builder,
|
||||
@FlywayDataSource DataSource flywayDataSource) {
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
properties.put("configured", "flyway");
|
||||
properties.put("hibernate.transaction.jta.platform", NoJtaPlatform.INSTANCE);
|
||||
return builder.dataSource(flywayDataSource).properties(properties).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class CustomFlywayWithJdbcConfiguration {
|
||||
|
||||
|
@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.liquibase;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@ -26,6 +27,7 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
@ -33,6 +35,10 @@ import java.util.function.Consumer;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.Id;
|
||||
import liquibase.Liquibase;
|
||||
import liquibase.UpdateSummaryEnum;
|
||||
import liquibase.UpdateSummaryOutputEnum;
|
||||
@ -40,6 +46,7 @@ import liquibase.command.core.helpers.ShowSummaryArgument;
|
||||
import liquibase.integration.spring.Customizer;
|
||||
import liquibase.integration.spring.SpringLiquibase;
|
||||
import liquibase.ui.UIServiceEnum;
|
||||
import org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
@ -49,6 +56,7 @@ import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
|
||||
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
|
||||
@ -56,6 +64,8 @@ import org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration.LiquibaseAutoConfigurationRuntimeHints;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
|
||||
import org.springframework.boot.jdbc.DataSourceBuilder;
|
||||
import org.springframework.boot.jdbc.EmbeddedDatabaseConnection;
|
||||
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
@ -71,6 +81,7 @@ import org.springframework.jdbc.datasource.SimpleDriverDataSource;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@ -549,6 +560,38 @@ class LiquibaseAutoConfigurationTests {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithDbChangelogMasterYamlResource
|
||||
@WithMetaInfPersistenceXmlResource
|
||||
void jpaApplyDdl() {
|
||||
this.contextRunner
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class))
|
||||
.run((context) -> {
|
||||
Map<String, Object> jpaProperties = context.getBean(LocalContainerEntityManagerFactoryBean.class)
|
||||
.getJpaPropertyMap();
|
||||
assertThat(jpaProperties).doesNotContainKey("hibernate.hbm2ddl.auto");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithDbChangelogMasterYamlResource
|
||||
@WithMetaInfPersistenceXmlResource
|
||||
void jpaAndMultipleDataSourcesApplyDdl() {
|
||||
this.contextRunner.withConfiguration(AutoConfigurations.of(HibernateJpaAutoConfiguration.class))
|
||||
.withUserConfiguration(JpaWithMultipleDataSourcesConfiguration.class)
|
||||
.run((context) -> {
|
||||
LocalContainerEntityManagerFactoryBean normalEntityManagerFactoryBean = context
|
||||
.getBean("&normalEntityManagerFactory", LocalContainerEntityManagerFactoryBean.class);
|
||||
assertThat(normalEntityManagerFactoryBean.getJpaPropertyMap()).containsEntry("configured", "normal")
|
||||
.containsEntry("hibernate.hbm2ddl.auto", "create-drop");
|
||||
LocalContainerEntityManagerFactoryBean liquibaseEntityManagerFactory = context
|
||||
.getBean("&liquibaseEntityManagerFactory", LocalContainerEntityManagerFactoryBean.class);
|
||||
assertThat(liquibaseEntityManagerFactory.getJpaPropertyMap()).containsEntry("configured", "liquibase")
|
||||
.doesNotContainKey("hibernate.hbm2ddl.auto");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithDbChangelogMasterYamlResource
|
||||
void userConfigurationJdbcTemplateDependency() {
|
||||
@ -669,6 +712,46 @@ class LiquibaseAutoConfigurationTests {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class JpaWithMultipleDataSourcesConfiguration {
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
DataSource normalDataSource() {
|
||||
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseConnection.HSQLDB.getType())
|
||||
.generateUniqueName(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
LocalContainerEntityManagerFactoryBean normalEntityManagerFactory(EntityManagerFactoryBuilder builder,
|
||||
DataSource normalDataSource) {
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
properties.put("configured", "normal");
|
||||
properties.put("hibernate.transaction.jta.platform", NoJtaPlatform.INSTANCE);
|
||||
return builder.dataSource(normalDataSource).properties(properties).build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@LiquibaseDataSource
|
||||
DataSource liquibaseDataSource() {
|
||||
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseConnection.HSQLDB.getType())
|
||||
.generateUniqueName(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
LocalContainerEntityManagerFactoryBean liquibaseEntityManagerFactory(EntityManagerFactoryBuilder builder,
|
||||
@LiquibaseDataSource DataSource liquibaseDataSource) {
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
properties.put("configured", "liquibase");
|
||||
properties.put("hibernate.transaction.jta.platform", NoJtaPlatform.INSTANCE);
|
||||
return builder.dataSource(liquibaseDataSource).properties(properties).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class CustomDataSourceConfiguration {
|
||||
|
||||
@ -805,4 +888,74 @@ class LiquibaseAutoConfigurationTests {
|
||||
|
||||
}
|
||||
|
||||
@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.autoconfigure.flyway.FlywayAutoConfigurationTests$City</class>
|
||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||
</persistence-unit>
|
||||
</persistence>
|
||||
""")
|
||||
@interface WithMetaInfPersistenceXmlResource {
|
||||
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class City implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String name;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String state;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String country;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String map;
|
||||
|
||||
protected City() {
|
||||
}
|
||||
|
||||
City(String name, String state, String country, String map) {
|
||||
this.name = name;
|
||||
this.state = state;
|
||||
this.country = country;
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return this.state;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return this.country;
|
||||
}
|
||||
|
||||
public String getMap() {
|
||||
return this.map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName() + "," + getState() + "," + getCountry();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@ -81,7 +81,8 @@ class CustomHibernateJpaAutoConfigurationTests {
|
||||
.withPropertyValues("spring.datasource.url:jdbc:h2:mem:naming-strategy-beans")
|
||||
.run((context) -> {
|
||||
HibernateJpaConfiguration jpaConfiguration = context.getBean(HibernateJpaConfiguration.class);
|
||||
Map<String, Object> hibernateProperties = jpaConfiguration.getVendorProperties();
|
||||
Map<String, Object> hibernateProperties = jpaConfiguration
|
||||
.getVendorProperties(context.getBean(DataSource.class));
|
||||
assertThat(hibernateProperties).containsEntry("hibernate.implicit_naming_strategy",
|
||||
NamingStrategyConfiguration.implicitNamingStrategy);
|
||||
assertThat(hibernateProperties).containsEntry("hibernate.physical_naming_strategy",
|
||||
@ -93,7 +94,8 @@ class CustomHibernateJpaAutoConfigurationTests {
|
||||
void hibernatePropertiesCustomizersAreAppliedInOrder() {
|
||||
this.contextRunner.withUserConfiguration(HibernatePropertiesCustomizerConfiguration.class).run((context) -> {
|
||||
HibernateJpaConfiguration jpaConfiguration = context.getBean(HibernateJpaConfiguration.class);
|
||||
Map<String, Object> hibernateProperties = jpaConfiguration.getVendorProperties();
|
||||
Map<String, Object> hibernateProperties = jpaConfiguration
|
||||
.getVendorProperties(context.getBean(DataSource.class));
|
||||
assertThat(hibernateProperties).containsEntry("test.counter", 2);
|
||||
});
|
||||
}
|
||||
|
@ -75,6 +75,7 @@ import org.springframework.boot.test.context.runner.ContextConsumer;
|
||||
import org.springframework.boot.testsupport.classpath.resources.WithResource;
|
||||
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.event.ContextRefreshedEvent;
|
||||
@ -419,8 +420,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
|
||||
@Test
|
||||
void physicalNamingStrategyCanBeUsed() {
|
||||
contextRunner().withUserConfiguration(TestPhysicalNamingStrategyConfiguration.class).run((context) -> {
|
||||
Map<String, Object> hibernateProperties = context.getBean(HibernateJpaConfiguration.class)
|
||||
.getVendorProperties();
|
||||
Map<String, Object> hibernateProperties = getVendorProperties(context);
|
||||
assertThat(hibernateProperties)
|
||||
.contains(entry("hibernate.physical_naming_strategy", context.getBean("testPhysicalNamingStrategy")));
|
||||
assertThat(hibernateProperties).doesNotContainKeys("hibernate.ejb.naming_strategy");
|
||||
@ -430,8 +430,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
|
||||
@Test
|
||||
void implicitNamingStrategyCanBeUsed() {
|
||||
contextRunner().withUserConfiguration(TestImplicitNamingStrategyConfiguration.class).run((context) -> {
|
||||
Map<String, Object> hibernateProperties = context.getBean(HibernateJpaConfiguration.class)
|
||||
.getVendorProperties();
|
||||
Map<String, Object> hibernateProperties = getVendorProperties(context);
|
||||
assertThat(hibernateProperties)
|
||||
.contains(entry("hibernate.implicit_naming_strategy", context.getBean("testImplicitNamingStrategy")));
|
||||
assertThat(hibernateProperties).doesNotContainKeys("hibernate.ejb.naming_strategy");
|
||||
@ -446,8 +445,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
|
||||
.withPropertyValues("spring.jpa.hibernate.naming.physical-strategy:com.example.Physical",
|
||||
"spring.jpa.hibernate.naming.implicit-strategy:com.example.Implicit")
|
||||
.run((context) -> {
|
||||
Map<String, Object> hibernateProperties = context.getBean(HibernateJpaConfiguration.class)
|
||||
.getVendorProperties();
|
||||
Map<String, Object> hibernateProperties = getVendorProperties(context);
|
||||
assertThat(hibernateProperties).contains(
|
||||
entry("hibernate.physical_naming_strategy", context.getBean("testPhysicalNamingStrategy")),
|
||||
entry("hibernate.implicit_naming_strategy", context.getBean("testImplicitNamingStrategy")));
|
||||
@ -463,8 +461,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
|
||||
.withPropertyValues("spring.jpa.hibernate.naming.physical-strategy:com.example.Physical",
|
||||
"spring.jpa.hibernate.naming.implicit-strategy:com.example.Implicit")
|
||||
.run((context) -> {
|
||||
Map<String, Object> hibernateProperties = context.getBean(HibernateJpaConfiguration.class)
|
||||
.getVendorProperties();
|
||||
Map<String, Object> hibernateProperties = getVendorProperties(context);
|
||||
TestHibernatePropertiesCustomizerConfiguration configuration = context
|
||||
.getBean(TestHibernatePropertiesCustomizerConfiguration.class);
|
||||
assertThat(hibernateProperties).contains(
|
||||
@ -556,8 +553,11 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
|
||||
|
||||
private ContextConsumer<AssertableApplicationContext> vendorProperties(
|
||||
Consumer<Map<String, Object>> vendorProperties) {
|
||||
return (context) -> vendorProperties
|
||||
.accept(context.getBean(HibernateJpaConfiguration.class).getVendorProperties());
|
||||
return (context) -> vendorProperties.accept(getVendorProperties(context));
|
||||
}
|
||||
|
||||
private static Map<String, Object> getVendorProperties(ConfigurableApplicationContext context) {
|
||||
return context.getBean(HibernateJpaConfiguration.class).getVendorProperties(context.getBean(DataSource.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -16,6 +16,10 @@
|
||||
|
||||
package org.springframework.boot.docs.howto.dataaccess.usemultipleentitymanagers;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
@ -48,7 +52,9 @@ public class MyAdditionalEntityManagerFactoryConfiguration {
|
||||
|
||||
private EntityManagerFactoryBuilder createEntityManagerFactoryBuilder(JpaProperties jpaProperties) {
|
||||
JpaVendorAdapter jpaVendorAdapter = createJpaVendorAdapter(jpaProperties);
|
||||
return new EntityManagerFactoryBuilder(jpaVendorAdapter, jpaProperties.getProperties(), null);
|
||||
Function<DataSource, Map<String, ?>> jpaPropertiesFactory = (dataSource) -> createJpaProperties(dataSource,
|
||||
jpaProperties.getProperties());
|
||||
return new EntityManagerFactoryBuilder(jpaVendorAdapter, jpaPropertiesFactory, null);
|
||||
}
|
||||
|
||||
private JpaVendorAdapter createJpaVendorAdapter(JpaProperties jpaProperties) {
|
||||
@ -56,4 +62,10 @@ public class MyAdditionalEntityManagerFactoryConfiguration {
|
||||
return new HibernateJpaVendorAdapter();
|
||||
}
|
||||
|
||||
private Map<String, ?> createJpaProperties(DataSource dataSource, Map<String, ?> existingProperties) {
|
||||
Map<String, ?> jpaProperties = new LinkedHashMap<>(existingProperties);
|
||||
// ... map JPA properties that require the DataSource (e.g. DDL flags)
|
||||
return jpaProperties;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.boot.docs.howto.dataaccess.usemultipleentitymanagers
|
||||
|
||||
import javax.sql.DataSource
|
||||
|
||||
import org.springframework.beans.factory.annotation.Qualifier
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties
|
||||
@ -27,6 +25,7 @@ import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.orm.jpa.JpaVendorAdapter
|
||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
|
||||
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter
|
||||
import javax.sql.DataSource
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ -51,7 +50,9 @@ class MyAdditionalEntityManagerFactoryConfiguration {
|
||||
|
||||
private fun createEntityManagerFactoryBuilder(jpaProperties: JpaProperties): EntityManagerFactoryBuilder {
|
||||
val jpaVendorAdapter = createJpaVendorAdapter(jpaProperties)
|
||||
return EntityManagerFactoryBuilder(jpaVendorAdapter, jpaProperties.properties, null)
|
||||
val jpaPropertiesFactory = { dataSource: DataSource ->
|
||||
createJpaProperties(dataSource, jpaProperties.properties) }
|
||||
return EntityManagerFactoryBuilder(jpaVendorAdapter, jpaPropertiesFactory, null)
|
||||
}
|
||||
|
||||
private fun createJpaVendorAdapter(jpaProperties: JpaProperties): JpaVendorAdapter {
|
||||
@ -59,4 +60,10 @@ class MyAdditionalEntityManagerFactoryConfiguration {
|
||||
return HibernateJpaVendorAdapter()
|
||||
}
|
||||
|
||||
private fun createJpaProperties(dataSource: DataSource, existingProperties: Map<String, *>): Map<String, *> {
|
||||
val jpaProperties: Map<String, *> = LinkedHashMap(existingProperties)
|
||||
// ... map JPA properties that require the DataSource (e.g. DDL flags)
|
||||
return jpaProperties
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@ -22,6 +22,7 @@ import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
@ -54,7 +55,7 @@ public class EntityManagerFactoryBuilder {
|
||||
|
||||
private final PersistenceUnitManager persistenceUnitManager;
|
||||
|
||||
private final Map<String, Object> jpaProperties;
|
||||
private final Function<DataSource, Map<String, ?>> jpaPropertiesFactory;
|
||||
|
||||
private final URL persistenceUnitRootLocation;
|
||||
|
||||
@ -62,6 +63,42 @@ public class EntityManagerFactoryBuilder {
|
||||
|
||||
private PersistenceUnitPostProcessor[] persistenceUnitPostProcessors;
|
||||
|
||||
/**
|
||||
* Create a new instance passing in the common pieces that will be shared if multiple
|
||||
* EntityManagerFactory instances are created.
|
||||
* @param jpaVendorAdapter a vendor adapter
|
||||
* @param jpaPropertiesFactory the JPA properties to be passed to the persistence
|
||||
* provider, based on the {@linkplain #dataSource(DataSource) configured data source}
|
||||
* @param persistenceUnitManager optional source of persistence unit information (can
|
||||
* be null)
|
||||
* @since 3.4.4
|
||||
*/
|
||||
public EntityManagerFactoryBuilder(JpaVendorAdapter jpaVendorAdapter,
|
||||
Function<DataSource, Map<String, ?>> jpaPropertiesFactory, PersistenceUnitManager persistenceUnitManager) {
|
||||
this(jpaVendorAdapter, jpaPropertiesFactory, persistenceUnitManager, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance passing in the common pieces that will be shared if multiple
|
||||
* EntityManagerFactory instances are created.
|
||||
* @param jpaVendorAdapter a vendor adapter
|
||||
* @param jpaPropertiesFactory the JPA properties to be passed to the persistence
|
||||
* provider, based on the {@linkplain #dataSource(DataSource) configured data source}
|
||||
* @param persistenceUnitManager optional source of persistence unit information (can
|
||||
* be null)
|
||||
* @param persistenceUnitRootLocation the persistence unit root location to use as a
|
||||
* fallback or {@code null}
|
||||
* @since 3.4.4
|
||||
*/
|
||||
public EntityManagerFactoryBuilder(JpaVendorAdapter jpaVendorAdapter,
|
||||
Function<DataSource, Map<String, ?>> jpaPropertiesFactory, PersistenceUnitManager persistenceUnitManager,
|
||||
URL persistenceUnitRootLocation) {
|
||||
this.jpaVendorAdapter = jpaVendorAdapter;
|
||||
this.persistenceUnitManager = persistenceUnitManager;
|
||||
this.jpaPropertiesFactory = jpaPropertiesFactory;
|
||||
this.persistenceUnitRootLocation = persistenceUnitRootLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance passing in the common pieces that will be shared if multiple
|
||||
* EntityManagerFactory instances are created.
|
||||
@ -69,10 +106,13 @@ public class EntityManagerFactoryBuilder {
|
||||
* @param jpaProperties the JPA properties to be passed to the persistence provider
|
||||
* @param persistenceUnitManager optional source of persistence unit information (can
|
||||
* be null)
|
||||
* @deprecated since 3.4.4 for removal in 3.6.0 in favor of
|
||||
* {@link #EntityManagerFactoryBuilder(JpaVendorAdapter, Function, PersistenceUnitManager)}
|
||||
*/
|
||||
@Deprecated(since = "3.4.4", forRemoval = true)
|
||||
public EntityManagerFactoryBuilder(JpaVendorAdapter jpaVendorAdapter, Map<String, ?> jpaProperties,
|
||||
PersistenceUnitManager persistenceUnitManager) {
|
||||
this(jpaVendorAdapter, jpaProperties, persistenceUnitManager, null);
|
||||
this(jpaVendorAdapter, (datasource) -> jpaProperties, persistenceUnitManager, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -85,15 +125,21 @@ public class EntityManagerFactoryBuilder {
|
||||
* @param persistenceUnitRootLocation the persistence unit root location to use as a
|
||||
* fallback or {@code null}
|
||||
* @since 1.4.1
|
||||
* @deprecated since 3.4.4 for removal in 3.6.0 in favor of
|
||||
* {@link #EntityManagerFactoryBuilder(JpaVendorAdapter, Function, PersistenceUnitManager, URL)}
|
||||
*/
|
||||
@Deprecated(since = "3.4.4", forRemoval = true)
|
||||
public EntityManagerFactoryBuilder(JpaVendorAdapter jpaVendorAdapter, Map<String, ?> jpaProperties,
|
||||
PersistenceUnitManager persistenceUnitManager, URL persistenceUnitRootLocation) {
|
||||
this.jpaVendorAdapter = jpaVendorAdapter;
|
||||
this.persistenceUnitManager = persistenceUnitManager;
|
||||
this.jpaProperties = new LinkedHashMap<>(jpaProperties);
|
||||
this.persistenceUnitRootLocation = persistenceUnitRootLocation;
|
||||
this(jpaVendorAdapter, (datasource) -> jpaProperties, persistenceUnitManager, persistenceUnitRootLocation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link Builder} for a {@code EntityManagerFactory} using the settings
|
||||
* of the given instance, and the given {@link DataSource}.
|
||||
* @param dataSource the data source to use
|
||||
* @return a builder to create an {@code EntityManagerFactory}
|
||||
*/
|
||||
public Builder dataSource(DataSource dataSource) {
|
||||
return new Builder(dataSource);
|
||||
}
|
||||
@ -255,7 +301,8 @@ public class EntityManagerFactoryBuilder {
|
||||
else {
|
||||
entityManagerFactoryBean.setPackagesToScan(this.packagesToScan);
|
||||
}
|
||||
entityManagerFactoryBean.getJpaPropertyMap().putAll(EntityManagerFactoryBuilder.this.jpaProperties);
|
||||
Map<String, ?> jpaProperties = EntityManagerFactoryBuilder.this.jpaPropertiesFactory.apply(this.dataSource);
|
||||
entityManagerFactoryBean.getJpaPropertyMap().putAll(new LinkedHashMap<>(jpaProperties));
|
||||
entityManagerFactoryBean.getJpaPropertyMap().putAll(this.properties);
|
||||
if (!ObjectUtils.isEmpty(this.mappingResources)) {
|
||||
entityManagerFactoryBean.setMappingResources(this.mappingResources);
|
||||
|
Loading…
x
Reference in New Issue
Block a user