Browse Source

Merge pull request #47802 from Asanio06

* pr/47802:
  Polish contribution
  Add support for configuring additional PersistenceUnitPostProcessor

Closes gh-47802
pull/48596/head
Stéphane Nicoll 3 months ago
parent
commit
cf3c2a086d
  1. 31
      module/spring-boot-hibernate/src/test/java/org/springframework/boot/hibernate/autoconfigure/HibernateJpaAutoConfigurationTests.java
  2. 1
      module/spring-boot-jpa/build.gradle
  3. 26
      module/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/EntityManagerFactoryBuilder.java
  4. 104
      module/spring-boot-jpa/src/test/java/org/springframework/boot/jpa/EntityManagerFactoryBuilderTests.java

31
module/spring-boot-hibernate/src/test/java/org/springframework/boot/hibernate/autoconfigure/HibernateJpaAutoConfigurationTests.java

@ -351,6 +351,19 @@ class HibernateJpaAutoConfigurationTests { @@ -351,6 +351,19 @@ class HibernateJpaAutoConfigurationTests {
});
}
@Test
void customPersistenceUnitProcessorsAddedByServeralContributors() {
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.anotherName");
});
}
@Test
void customManagedClassNameFilter() {
this.contextRunner.withBean(ManagedClassNameFilter.class, () -> (s) -> !s.endsWith("City"))
@ -1168,6 +1181,24 @@ class HibernateJpaAutoConfigurationTests { @@ -1168,6 +1181,24 @@ class HibernateJpaAutoConfigurationTests {
}
@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 anotherEntityManagerFactoryBuilderCustomizer() {
return (builder) -> builder.addPersistenceUnitPostProcessors(
(pui) -> pui.addManagedClassName("customized.attribute.converter.class.anotherName"));
}
}
static class CustomJpaTransactionManager extends JpaTransactionManager {
}

1
module/spring-boot-jpa/build.gradle

@ -36,7 +36,6 @@ dependencies { @@ -36,7 +36,6 @@ dependencies {
testImplementation(project(":core:spring-boot-test"))
testImplementation(project(":test-support:spring-boot-test-support"))
testImplementation(testFixtures(project(":core:spring-boot-autoconfigure")))
testImplementation("org.springframework:spring-context-support")
}
tasks.named("compileTestJava") {

26
module/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/EntityManagerFactoryBuilder.java

@ -17,9 +17,12 @@ @@ -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;
@ -63,7 +66,7 @@ public class EntityManagerFactoryBuilder { @@ -63,7 +66,7 @@ public class EntityManagerFactoryBuilder {
private @Nullable AsyncTaskExecutor bootstrapExecutor;
private PersistenceUnitPostProcessor @Nullable [] persistenceUnitPostProcessors;
private @Nullable List<PersistenceUnitPostProcessor> persistenceUnitPostProcessors;
/**
* Create a new instance passing in the common pieces that will be shared if multiple
@ -126,7 +129,23 @@ public class EntityManagerFactoryBuilder { @@ -126,7 +129,23 @@ public class EntityManagerFactoryBuilder {
* @param persistenceUnitPostProcessors the persistence unit post processors to use
*/
public void setPersistenceUnitPostProcessors(PersistenceUnitPostProcessor... persistenceUnitPostProcessors) {
this.persistenceUnitPostProcessors = persistenceUnitPostProcessors;
this.persistenceUnitPostProcessors = new ArrayList<>(Arrays.asList(persistenceUnitPostProcessors));
}
/**
* Add {@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 add
* @since 4.1.0
*/
public void addPersistenceUnitPostProcessors(PersistenceUnitPostProcessor... persistenceUnitPostProcessors) {
if (this.persistenceUnitPostProcessors != null) {
this.persistenceUnitPostProcessors.addAll(Arrays.asList(persistenceUnitPostProcessors));
}
else {
setPersistenceUnitPostProcessors(persistenceUnitPostProcessors);
}
}
/**
@ -280,7 +299,8 @@ public class EntityManagerFactoryBuilder { @@ -280,7 +299,8 @@ public class EntityManagerFactoryBuilder {
}
if (EntityManagerFactoryBuilder.this.persistenceUnitPostProcessors != null) {
entityManagerFactoryBean
.setPersistenceUnitPostProcessors(EntityManagerFactoryBuilder.this.persistenceUnitPostProcessors);
.setPersistenceUnitPostProcessors(EntityManagerFactoryBuilder.this.persistenceUnitPostProcessors
.toArray(PersistenceUnitPostProcessor[]::new));
}
return entityManagerFactoryBean;
}

104
module/spring-boot-jpa/src/test/java/org/springframework/boot/jpa/EntityManagerFactoryBuilderTests.java

@ -0,0 +1,104 @@ @@ -0,0 +1,104 @@
/*
* 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;
import java.util.Collections;
import java.util.Map;
import java.util.function.Function;
import javax.sql.DataSource;
import jakarta.persistence.spi.PersistenceProvider;
import org.assertj.core.api.InstanceOfAssertFactories;
import org.junit.jupiter.api.Test;
import org.springframework.orm.jpa.persistenceunit.PersistenceUnitPostProcessor;
import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link EntityManagerFactoryBuilder}.
*
* @author Stephane Nicoll
*/
class EntityManagerFactoryBuilderTests {
@Test
void setPersistenceUnitPostProcessorsWhenEmpty() {
EntityManagerFactoryBuilder builder = createEmptyBuilder();
PersistenceUnitPostProcessor postProcessor = mock();
PersistenceUnitPostProcessor postProcessor2 = mock();
builder.setPersistenceUnitPostProcessors(postProcessor, postProcessor2);
assertThat(builder).extracting("persistenceUnitPostProcessors")
.asInstanceOf(InstanceOfAssertFactories.LIST)
.containsExactly(postProcessor, postProcessor2);
}
@Test
void addPersistenceUnitPostProcessorsWhenEmpty() {
EntityManagerFactoryBuilder builder = createEmptyBuilder();
PersistenceUnitPostProcessor postProcessor = mock();
PersistenceUnitPostProcessor postProcessor2 = mock();
builder.addPersistenceUnitPostProcessors(postProcessor, postProcessor2);
assertThat(builder).extracting("persistenceUnitPostProcessors")
.asInstanceOf(InstanceOfAssertFactories.LIST)
.containsExactly(postProcessor, postProcessor2);
}
@Test
void setPersistenceUnitPostProcessorsWhenNotEmpty() {
EntityManagerFactoryBuilder builder = createEmptyBuilder();
PersistenceUnitPostProcessor postProcessor = mock();
builder.addPersistenceUnitPostProcessors(postProcessor);
PersistenceUnitPostProcessor postProcessor2 = mock();
PersistenceUnitPostProcessor postProcessor3 = mock();
builder.setPersistenceUnitPostProcessors(postProcessor2, postProcessor3);
assertThat(builder).extracting("persistenceUnitPostProcessors")
.asInstanceOf(InstanceOfAssertFactories.LIST)
.containsExactly(postProcessor2, postProcessor3);
}
@Test
void addPersistenceUnitPostProcessorsWhenNotEmpty() {
EntityManagerFactoryBuilder builder = createEmptyBuilder();
PersistenceUnitPostProcessor postProcessor = mock();
builder.addPersistenceUnitPostProcessors(postProcessor);
PersistenceUnitPostProcessor postProcessor2 = mock();
builder.addPersistenceUnitPostProcessors(postProcessor2);
assertThat(builder).extracting("persistenceUnitPostProcessors")
.asInstanceOf(InstanceOfAssertFactories.LIST)
.containsExactly(postProcessor, postProcessor2);
}
private EntityManagerFactoryBuilder createEmptyBuilder() {
Function<DataSource, Map<String, ?>> jpaPropertiesFactory = (dataSource) -> Collections
.emptyMap();
return new EntityManagerFactoryBuilder(new TestJpaVendorAdapter(), jpaPropertiesFactory, null);
}
static class TestJpaVendorAdapter extends AbstractJpaVendorAdapter {
@Override
public PersistenceProvider getPersistenceProvider() {
return mock();
}
}
}
Loading…
Cancel
Save