Skip to content

Commit 8f4156b

Browse files
christophstroblgregturn
authored andcommitted
Disable domain type inspection.
JPA managed types are now registered via PersistenceManagedTypes in spring.orm so there is no need to do it twice. See #2628.
1 parent 91ba4e2 commit 8f4156b

File tree

3 files changed

+161
-4
lines changed

3 files changed

+161
-4
lines changed

spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/config/JpaRepositoryConfigExtension.java

+23
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
import java.util.Optional;
3434
import java.util.Set;
3535

36+
import org.springframework.aot.generate.GenerationContext;
37+
import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor;
3638
import org.springframework.beans.factory.config.BeanDefinition;
3739
import org.springframework.beans.factory.support.AbstractBeanDefinition;
3840
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
@@ -44,6 +46,8 @@
4446
import org.springframework.core.io.ResourceLoader;
4547
import org.springframework.dao.DataAccessException;
4648
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
49+
import org.springframework.data.aot.AotRepositoryContext;
50+
import org.springframework.data.aot.RepositoryRegistrationAotProcessor;
4751
import org.springframework.data.jpa.repository.JpaRepository;
4852
import org.springframework.data.jpa.repository.support.DefaultJpaContext;
4953
import org.springframework.data.jpa.repository.support.EntityManagerBeanDefinitionRegistrarPostProcessor;
@@ -118,6 +122,11 @@ public void postProcess(BeanDefinitionBuilder builder, RepositoryConfigurationSo
118122
builder.addPropertyReference("mappingContext", JPA_MAPPING_CONTEXT_BEAN_NAME);
119123
}
120124

125+
@Override
126+
public Class<? extends BeanRegistrationAotProcessor> getRepositoryAotProcessor() {
127+
return JpaRepositoryRegistrationAotProcessor.class;
128+
}
129+
121130
/**
122131
* XML configurations do not support {@link Character} values. This method catches the exception thrown and returns an
123132
* {@link Optional#empty()} instead.
@@ -285,4 +294,18 @@ static boolean isActive(@Nullable ClassLoader classLoader) {
285294
.anyMatch(agentClass -> ClassUtils.isPresent(agentClass, classLoader));
286295
}
287296
}
297+
298+
/**
299+
* A {@link RepositoryRegistrationAotProcessor} implementation that maintains aot repository setup but skips domain
300+
* type inspection which is handled by the core framework support for
301+
* {@link org.springframework.orm.jpa.persistenceunit.PersistenceManagedTypes}.
302+
*
303+
* @since 3.0
304+
*/
305+
public static class JpaRepositoryRegistrationAotProcessor extends RepositoryRegistrationAotProcessor {
306+
307+
protected void contribute(AotRepositoryContext repositoryContext, GenerationContext generationContext) {
308+
// don't register domain types nor annotations.
309+
}
310+
}
288311
}

spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/config/JpaRepositoryConfigExtensionUnitTests.java

+10-4
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,18 @@
1818
import static org.assertj.core.api.Assertions.*;
1919
import static org.mockito.Mockito.*;
2020

21-
import java.util.Arrays;
22-
import java.util.Collections;
23-
2421
import jakarta.persistence.EntityManagerFactory;
2522
import jakarta.persistence.metamodel.Metamodel;
2623

24+
import java.util.Arrays;
25+
import java.util.Collections;
26+
2727
import org.junit.jupiter.api.Test;
2828
import org.junit.jupiter.api.extension.ExtendWith;
2929
import org.mockito.Mock;
3030
import org.mockito.junit.jupiter.MockitoExtension;
3131
import org.mockito.junit.jupiter.MockitoSettings;
3232
import org.mockito.quality.Strictness;
33-
3433
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
3534
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
3635
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
@@ -141,6 +140,13 @@ public Class<?> loadClass(String name) throws ClassNotFoundException {
141140
assertThat(classLoader).isNotInstanceOf(InspectionClassLoader.class);
142141
}
143142

143+
@Test // GH-2628
144+
void exposesJpaAotProcessor() {
145+
146+
assertThat(new JpaRepositoryConfigExtension().getRepositoryAotProcessor())
147+
.isEqualTo(JpaRepositoryConfigExtension.JpaRepositoryRegistrationAotProcessor.class);
148+
}
149+
144150
private void assertOnlyOnePersistenceAnnotationBeanPostProcessorRegistered(DefaultListableBeanFactory factory,
145151
String expectedBeanName) {
146152

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
2+
* Copyright 2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.jpa.repository.config;
17+
18+
import static org.assertj.core.api.Assertions.*;
19+
20+
import jakarta.persistence.Entity;
21+
22+
import java.lang.annotation.Annotation;
23+
import java.util.Collections;
24+
import java.util.Set;
25+
26+
import org.junit.jupiter.api.Test;
27+
import org.springframework.aot.generate.ClassNameGenerator;
28+
import org.springframework.aot.generate.DefaultGenerationContext;
29+
import org.springframework.aot.generate.GenerationContext;
30+
import org.springframework.aot.generate.InMemoryGeneratedFiles;
31+
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
32+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
33+
import org.springframework.core.annotation.MergedAnnotation;
34+
import org.springframework.data.aot.AotRepositoryContext;
35+
import org.springframework.data.repository.core.RepositoryInformation;
36+
37+
/**
38+
* @author Christoph Strobl
39+
*/
40+
class JpaRepositoryRegistrationAotProcessorUnitTests {
41+
42+
@Test // GH-2628
43+
void aotProcessorMustNotRegisterDomainTypes() {
44+
45+
GenerationContext ctx = new DefaultGenerationContext(new ClassNameGenerator(Object.class),
46+
new InMemoryGeneratedFiles());
47+
48+
new JpaRepositoryConfigExtension.JpaRepositoryRegistrationAotProcessor()
49+
.contribute(new DummyAotRepositoryContext() {
50+
@Override
51+
public Set<Class<?>> getResolvedTypes() {
52+
return Collections.singleton(Person.class);
53+
}
54+
}, ctx);
55+
56+
assertThat(RuntimeHintsPredicates.reflection().onType(Person.class)).rejects(ctx.getRuntimeHints());
57+
}
58+
59+
@Test // GH-2628
60+
void aotProcessorMustNotRegisterAnnotations() {
61+
62+
GenerationContext ctx = new DefaultGenerationContext(new ClassNameGenerator(Object.class),
63+
new InMemoryGeneratedFiles());
64+
65+
new JpaRepositoryConfigExtension.JpaRepositoryRegistrationAotProcessor()
66+
.contribute(new DummyAotRepositoryContext() {
67+
68+
@Override
69+
public Set<MergedAnnotation<Annotation>> getResolvedAnnotations() {
70+
71+
MergedAnnotation mergedAnnotation = MergedAnnotation.of(Entity.class);
72+
return Set.of(mergedAnnotation);
73+
}
74+
}, ctx);
75+
76+
assertThat(RuntimeHintsPredicates.reflection().onType(Entity.class)).rejects(ctx.getRuntimeHints());
77+
}
78+
79+
static class Person {}
80+
81+
static class DummyAotRepositoryContext implements AotRepositoryContext {
82+
83+
@Override
84+
public String getBeanName() {
85+
return "jpaRepository";
86+
}
87+
88+
@Override
89+
public Set<String> getBasePackages() {
90+
return Collections.singleton(this.getClass().getPackageName());
91+
}
92+
93+
@Override
94+
public Set<Class<? extends Annotation>> getIdentifyingAnnotations() {
95+
return Collections.singleton(Entity.class);
96+
}
97+
98+
@Override
99+
public RepositoryInformation getRepositoryInformation() {
100+
return null;
101+
}
102+
103+
@Override
104+
public Set<MergedAnnotation<Annotation>> getResolvedAnnotations() {
105+
return null;
106+
}
107+
108+
@Override
109+
public Set<Class<?>> getResolvedTypes() {
110+
return null;
111+
}
112+
113+
@Override
114+
public ConfigurableListableBeanFactory getBeanFactory() {
115+
return null;
116+
}
117+
118+
@Override
119+
public TypeIntrospector introspectType(String typeName) {
120+
return null;
121+
}
122+
123+
@Override
124+
public IntrospectedBeanDefinition introspectBeanDefinition(String beanName) {
125+
return null;
126+
}
127+
}
128+
}

0 commit comments

Comments
 (0)