diff --git a/module/spring-boot-hibernate/src/test/java/org/springframework/boot/hibernate/autoconfigure/HibernateJpaAutoConfigurationTests.java b/module/spring-boot-hibernate/src/test/java/org/springframework/boot/hibernate/autoconfigure/HibernateJpaAutoConfigurationTests.java index 8df2dcdede3a..dfa2053f81d5 100644 --- a/module/spring-boot-hibernate/src/test/java/org/springframework/boot/hibernate/autoconfigure/HibernateJpaAutoConfigurationTests.java +++ b/module/spring-boot-hibernate/src/test/java/org/springframework/boot/hibernate/autoconfigure/HibernateJpaAutoConfigurationTests.java @@ -113,6 +113,7 @@ 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.persistenceunit.PersistenceUnitPostProcessor; import org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter; import org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; @@ -350,6 +351,19 @@ void customPersistenceUnitPostProcessors() { }); } + @Test + void shouldProcessAllPersistenceUnitPostProcessorsDeclaredAsBeans() { + this.contextRunner.withUserConfiguration(TestConfigurationWithMultipleCustomPersistenceUnitPostProcessors.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", "customized.attribute.converter.class.othername"); + }); + } + @Test void customManagedClassNameFilter() { this.contextRunner.withBean(ManagedClassNameFilter.class, () -> (s) -> !s.endsWith("City")) @@ -1149,6 +1163,24 @@ EntityManagerFactoryBuilderCustomizer entityManagerFactoryBuilderCustomizer() { } + @Configuration(proxyBeanMethods = false) + @TestAutoConfigurationPackage(HibernateJpaAutoConfigurationTests.class) + static class TestConfigurationWithMultipleCustomPersistenceUnitPostProcessors { + + @Bean + EntityManagerFactoryBuilderCustomizer entityManagerFactoryBuilderCustomizer() { + return (builder) -> builder.addPersistenceUnitPostProcessors( + (pui) -> pui.addManagedClassName("customized.attribute.converter.class.name")); + } + + @Bean + EntityManagerFactoryBuilderCustomizer otherEntityManagerFactoryBuilderCustomizer() { + return (builder) -> builder.addPersistenceUnitPostProcessors( + (pui) -> pui.addManagedClassName("customized.attribute.converter.class.othername")); + } + + } + static class CustomJpaTransactionManager extends JpaTransactionManager { } diff --git a/module/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/EntityManagerFactoryBuilder.java b/module/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/EntityManagerFactoryBuilder.java index 91ea4f9993cb..405dbadcbfdd 100644 --- a/module/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/EntityManagerFactoryBuilder.java +++ b/module/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/EntityManagerFactoryBuilder.java @@ -17,9 +17,12 @@ package org.springframework.boot.jpa; import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Function; @@ -129,6 +132,24 @@ public void setPersistenceUnitPostProcessors(PersistenceUnitPostProcessor... per this.persistenceUnitPostProcessors = persistenceUnitPostProcessors; } + /** + * Add some {@linkplain PersistenceUnitPostProcessor persistence unit post processors} + * to be applied to the PersistenceUnitInfo used for creating the + * {@link LocalContainerEntityManagerFactoryBean}. + * @param persistenceUnitPostProcessors the persistence unit post processors to use + */ + public void addPersistenceUnitPostProcessors(PersistenceUnitPostProcessor... persistenceUnitPostProcessors) { + if (this.persistenceUnitPostProcessors == null) { + this.persistenceUnitPostProcessors = persistenceUnitPostProcessors; + return; + } + + var combined = new ArrayList<>(Arrays.asList(this.persistenceUnitPostProcessors)); + combined.addAll(Arrays.asList(persistenceUnitPostProcessors)); + + this.persistenceUnitPostProcessors = combined.toArray(PersistenceUnitPostProcessor[]::new); + } + /** * A fluent builder for a LocalContainerEntityManagerFactoryBean. */