Browse Source

Fix `TypeInformation.OBJECT` initialization.

We now create a decoupled instance of ClassTypeInformation to avoid initialization visibility cycle issues when TypeInformation.OBJECT (and other fields) are initialized with null because ClassTypeInformation.OBJECT hasn't been initialized yet.

Closes #3340
3.5.x
Mark Paluch 5 months ago
parent
commit
375f97ee33
No known key found for this signature in database
GPG Key ID: 55BC6374BAA9D973
  1. 4
      src/main/java/org/springframework/data/util/ClassTypeInformation.java
  2. 10
      src/main/java/org/springframework/data/util/TypeInformation.java
  3. 18
      src/test/java/org/springframework/data/util/ClassTypeInformationUnitTests.java

4
src/main/java/org/springframework/data/util/ClassTypeInformation.java

@ -61,6 +61,10 @@ public class ClassTypeInformation<S> extends TypeDiscoverer<S> { @@ -61,6 +61,10 @@ public class ClassTypeInformation<S> extends TypeDiscoverer<S> {
private final Class<S> type;
ClassTypeInformation(Class<?> type) {
this(ResolvableType.forType(type));
}
ClassTypeInformation(ResolvableType type) {
super(type);
this.type = (Class<S>) type.resolve(Object.class);

10
src/main/java/org/springframework/data/util/TypeInformation.java

@ -42,11 +42,11 @@ import org.springframework.util.Assert; @@ -42,11 +42,11 @@ import org.springframework.util.Assert;
@SuppressWarnings({ "deprecation", "rawtypes" })
public interface TypeInformation<S> {
TypeInformation<Collection> COLLECTION = ClassTypeInformation.COLLECTION;
TypeInformation<List> LIST = ClassTypeInformation.LIST;
TypeInformation<Set> SET = ClassTypeInformation.SET;
TypeInformation<Map> MAP = ClassTypeInformation.MAP;
TypeInformation<Object> OBJECT = ClassTypeInformation.OBJECT;
TypeInformation<Collection> COLLECTION = new ClassTypeInformation(Collection.class);
TypeInformation<List> LIST = new ClassTypeInformation(List.class);
TypeInformation<Set> SET = new ClassTypeInformation(Set.class);
TypeInformation<Map> MAP = new ClassTypeInformation(Map.class);
TypeInformation<Object> OBJECT = new ClassTypeInformation(Object.class);
/**
* Creates a new {@link TypeInformation} from the given {@link ResolvableType}.

18
src/test/java/org/springframework/data/util/ClassTypeInformationUnitTests.java

@ -45,6 +45,24 @@ import org.springframework.lang.Nullable; @@ -45,6 +45,24 @@ import org.springframework.lang.Nullable;
*/
public class ClassTypeInformationUnitTests {
@Test // GH-3340
void typeInformationConstantsShouldNotBeNull() {
assertThat(ClassTypeInformation.COLLECTION).isNotNull();
assertThat(TypeInformation.COLLECTION).isNotNull();
assertThat(TypeInformation.LIST).isNotNull();
assertThat(TypeInformation.SET).isNotNull();
assertThat(TypeInformation.MAP).isNotNull();
assertThat(TypeInformation.OBJECT).isNotNull();
assertThat(ClassTypeInformation.OBJECT).isNotNull();
assertThat(TypeInformation.COLLECTION).isEqualTo(ClassTypeInformation.COLLECTION);
assertThat(TypeInformation.LIST).isEqualTo(ClassTypeInformation.LIST);
assertThat(TypeInformation.SET).isEqualTo(ClassTypeInformation.SET);
assertThat(TypeInformation.MAP).isEqualTo(ClassTypeInformation.MAP);
assertThat(TypeInformation.OBJECT).isEqualTo(ClassTypeInformation.OBJECT);
}
@Test
public void discoversTypeForSimpleGenericField() {

Loading…
Cancel
Save