Skip to content

Commit 85e257f

Browse files
committed
DATACMNS-1571 - Fixed specialization in ParameterizedTypeInformation.
DATACMNS-783 introduced code to specialize a raw type containing generics with the type information from it's context so that it can be established if only the raw type has been e.g. stored as type hint in a store (SomeType<T> stored as SomeType and T needing to be reestablished from the context). That application of the context unfortunately did not consider that the raw type might carry generics information itself, like `SomeType extends Foo<String, Integer>`. We've now changed the specialization algorithm so that the the target type is being looked at in the context of the type used for the assignment (e.g. `Foo<T, ID> foo`). If that assignment fully resolves the declared type, we just outright use the given type as it by definition carries all generics information plus better type information in the first place. If the type to specialize on is only partially expanding the generics we now create a synthetic type to merge the generics information. I.e. a `SomeType<T> extends Foo<T, Integer>` stored as SomeType would still resolve ID to Integer but capture T from the context including all potentially declared bounds. Related tickets: DATACMNS-783, DATACMNS-1138.
1 parent 150e327 commit 85e257f

File tree

2 files changed

+20
-5
lines changed

2 files changed

+20
-5
lines changed

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

+14-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,20 @@ protected TypeInformation<?> doGetComponentType() {
166166
@Override
167167
@SuppressWarnings("unchecked")
168168
public TypeInformation<? extends T> specialize(ClassTypeInformation<?> type) {
169-
return isResolvedCompletely() ? (TypeInformation<? extends T>) type : super.specialize(type);
169+
170+
if (isResolvedCompletely()) {
171+
return (TypeInformation<? extends T>) type;
172+
}
173+
174+
TypeInformation<?> asSupertype = type.getSuperTypeInformation(getType());
175+
176+
if (asSupertype == null || !ParameterizedTypeInformation.class.isInstance(asSupertype)) {
177+
return super.specialize(type);
178+
}
179+
180+
return ((ParameterizedTypeInformation<?>) asSupertype).isResolvedCompletely() //
181+
? (TypeInformation<? extends T>) type //
182+
: super.specialize(type);
170183
}
171184

172185
/*

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

+6-4
Original file line numberDiff line numberDiff line change
@@ -485,13 +485,15 @@ public boolean isAssignableFrom(TypeInformation<?> target) {
485485
@SuppressWarnings("unchecked")
486486
public TypeInformation<? extends S> specialize(ClassTypeInformation<?> type) {
487487

488+
Assert.notNull(type, "Type must not be null!");
488489
Assert.isTrue(getType().isAssignableFrom(type.getType()),
489-
String.format("%s must be assignable from %s", getType(), type.getType()));
490+
() -> String.format("%s must be assignable from %s", getType(), type.getType()));
490491

491-
List<TypeInformation<?>> arguments = getTypeArguments();
492+
List<TypeInformation<?>> typeArguments = getTypeArguments();
492493

493-
return (TypeInformation<? extends S>) (arguments.isEmpty() ? type
494-
: createInfo(new SyntheticParamterizedType(type, arguments)));
494+
return (TypeInformation<? extends S>) (typeArguments.isEmpty() //
495+
? type //
496+
: type.createInfo(new SyntheticParamterizedType(type, getTypeArguments())));
495497
}
496498

497499
@Nullable

0 commit comments

Comments
 (0)