Skip to content

Commit

Permalink
Consider nested generics in TypeDiscoverer equality comparison.
Browse files Browse the repository at this point in the history
We now compare nested generics wrapped into TypeInformation to consider type equality for deeply parametrized types.

Previously, we resolved type parameters to Class so Foo<List<String>> was considered equal to Foo<List<Map>> as the type parameter of the first nesting level was erased.

Closes spring-projects#3051
  • Loading branch information
mp911de committed Feb 27, 2024
1 parent 047b6be commit f7a1066
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class TypeDiscoverer<S> implements TypeInformation<S> {
private final Map<Constructor<?>, List<TypeInformation<?>>> constructorParameters = new ConcurrentHashMap<>();
private final Lazy<List<TypeInformation<?>>> typeArguments;

private final Lazy<List<Class>> resolvedGenerics;
private final Lazy<List<TypeInformation<?>>> resolvedGenerics;

protected TypeDiscoverer(ResolvableType type) {

Expand All @@ -71,7 +71,9 @@ protected TypeDiscoverer(ResolvableType type) {
this.valueType = Lazy.of(this::doGetMapValueType);
this.typeArguments = Lazy.of(this::doGetTypeArguments);
this.resolvedGenerics = Lazy.of(() -> Arrays.stream(resolvableType.getGenerics()) //
.map(ResolvableType::toClass).collect(Collectors.toList()));
.map(TypeInformation::of) // use TypeInformation comparison to remove any attachments to variableResolver
// holding the type source
.collect(Collectors.toList()));
}

static TypeDiscoverer<?> ofCached(ResolvableType type) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;

import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.core.ResolvableType;
import org.springframework.data.geo.GeoResults;
Expand Down Expand Up @@ -348,6 +349,15 @@ void differentEqualsAndHashCodeForTypeDiscovererAndClassTypeInformation() {
assertThat(discoverer.hashCode()).isNotEqualTo(classTypeInformation.hashCode());
}

@Test // GH-3051
void considersNestedGenericsInEquality() throws ReflectiveOperationException {

ResolvableType containerList = ResolvableType.forField(WithContainer.class.getDeclaredField("containerList"));
ResolvableType containerMap = ResolvableType.forField(WithContainer.class.getDeclaredField("containerMap"));

assertThat(TypeInformation.of(containerList)).isNotEqualTo(TypeInformation.of(containerMap));
}

class Person {

Addresses addresses;
Expand Down Expand Up @@ -441,4 +451,15 @@ class EnumMapWrapper {
class GeoResultsWrapper {
GeoResults<Leaf> results;
}

static class WithContainer {
MyContainer<List<String>> containerList;

MyContainer<List<Map<Long, Double>>> containerMap;
}

static class MyContainer<T> {
T data;
}

}

0 comments on commit f7a1066

Please sign in to comment.