Skip to content

Commit 8f4beff

Browse files
christophstroblmp911de
authored andcommitted
Collect constructor type information via Constructor.getParameters().
This commit fixes an issue where we fail to detect all type arguments from a given constructor. calling getGenericParameterTypes in some cases does not include all Types, we now explicitly iterate over the parameters and extract the parameterized type that is used for creating the TypeInformation. Closes: #2313 Original pull request: #2314.
1 parent 5454b37 commit 8f4beff

File tree

2 files changed

+48
-7
lines changed

2 files changed

+48
-7
lines changed

src/main/java/org/springframework/data/util/TypeDiscoverer.java

+5-7
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.lang.reflect.Field;
2121
import java.lang.reflect.GenericArrayType;
2222
import java.lang.reflect.Method;
23+
import java.lang.reflect.Parameter;
2324
import java.lang.reflect.ParameterizedType;
2425
import java.lang.reflect.Type;
2526
import java.lang.reflect.TypeVariable;
@@ -175,14 +176,11 @@ public List<TypeInformation<?>> getParameterTypes(Constructor<?> constructor) {
175176

176177
Assert.notNull(constructor, "Constructor must not be null!");
177178

178-
Type[] types = constructor.getGenericParameterTypes();
179-
List<TypeInformation<?>> result = new ArrayList<>(types.length);
180-
181-
for (Type parameterType : types) {
182-
result.add(createInfo(parameterType));
179+
List<TypeInformation<?>> parameterTypes = new ArrayList<>(constructor.getParameterCount());
180+
for(Parameter parameter : constructor.getParameters()) {
181+
parameterTypes.add(createInfo(parameter.getParameterizedType()));
183182
}
184-
185-
return result;
183+
return parameterTypes;
186184
}
187185

188186
/*

src/test/java/org/springframework/data/mapping/PreferredConstructorDiscovererUnitTests.java

+43
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
* @author Oliver Gierke
3434
* @author Roman Rodov
3535
* @author Mark Paluch
36+
* @author Christoph Strobl
3637
*/
3738
public class PreferredConstructorDiscovererUnitTests<P extends PersistentProperty<P>> {
3839

@@ -112,6 +113,30 @@ public void skipsSyntheticConstructor() {
112113
});
113114
}
114115

116+
@Test // GH-2313
117+
void capturesEnclosingTypeParameterOfNonStaticInnerClass() {
118+
119+
assertThat(PreferredConstructorDiscoverer.discover(NonStaticWithGenericTypeArgUsedInCtor.class))
120+
.satisfies(ctor -> {
121+
122+
assertThat(ctor.getParameters()).hasSize(2);
123+
assertThat(ctor.getParameters().get(0).getName()).isEqualTo("this$0");
124+
assertThat(ctor.getParameters().get(1).getName()).isEqualTo("value");
125+
});
126+
}
127+
128+
@Test // GH-2313
129+
void capturesSuperClassEnclosingTypeParameterOfNonStaticInnerClass() {
130+
131+
assertThat(PreferredConstructorDiscoverer.discover(NonStaticInnerWithGenericArgUsedInCtor.class))
132+
.satisfies(ctor -> {
133+
134+
assertThat(ctor.getParameters()).hasSize(2);
135+
assertThat(ctor.getParameters().get(0).getName()).isEqualTo("this$0");
136+
assertThat(ctor.getParameters().get(1).getName()).isEqualTo("value");
137+
});
138+
}
139+
115140
static class SyntheticConstructor {
116141
@PersistenceConstructor
117142
private SyntheticConstructor(String x) {}
@@ -164,4 +189,22 @@ class Inner {
164189

165190
}
166191
}
192+
193+
static class GenericTypeArgUsedInCtor<T> {
194+
195+
protected GenericTypeArgUsedInCtor(T value) {}
196+
}
197+
198+
199+
class NonStaticWithGenericTypeArgUsedInCtor<T> {
200+
201+
protected NonStaticWithGenericTypeArgUsedInCtor(T value) {}
202+
}
203+
204+
class NonStaticInnerWithGenericArgUsedInCtor<T> extends GenericTypeArgUsedInCtor<T> {
205+
206+
public NonStaticInnerWithGenericArgUsedInCtor(T value) {
207+
super(value);
208+
}
209+
}
167210
}

0 commit comments

Comments
 (0)