From 443da107796d50280ab8b286874fba8eae0fd41b Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Tue, 6 May 2014 09:45:38 +0200 Subject: [PATCH] DATACMNS-501 - Work around potential null returned from GenericTypeResolver in Spring 4. Spring 4's GenericTypeResolver returns null when trying to resolve type arguments for types that do not fully resolve the generic types. Related issues: SPR-11763. --- .../support/DefaultRepositoryMetadata.java | 21 +++++++++++-------- .../DefaultRepositoryMetadataUnitTests.java | 13 ++++++++++++ 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/springframework/data/repository/core/support/DefaultRepositoryMetadata.java b/src/main/java/org/springframework/data/repository/core/support/DefaultRepositoryMetadata.java index d6db24293..09218faff 100644 --- a/src/main/java/org/springframework/data/repository/core/support/DefaultRepositoryMetadata.java +++ b/src/main/java/org/springframework/data/repository/core/support/DefaultRepositoryMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2013 the original author or authors. + * Copyright 2011-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,12 +15,13 @@ */ package org.springframework.data.repository.core.support; -import static org.springframework.core.GenericTypeResolver.*; - import java.io.Serializable; +import java.util.List; import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.RepositoryMetadata; +import org.springframework.data.util.ClassTypeInformation; +import org.springframework.data.util.TypeInformation; import org.springframework.util.Assert; /** @@ -73,23 +74,25 @@ public class DefaultRepositoryMetadata extends AbstractRepositoryMetadata { @SuppressWarnings("unchecked") private Class resolveIdType(Class repositoryInterface) { - Class[] arguments = resolveTypeArguments(repositoryInterface, Repository.class); + TypeInformation information = ClassTypeInformation.from(repositoryInterface); + List> arguments = information.getSuperTypeInformation(Repository.class).getTypeArguments(); - if (arguments == null || arguments[1] == null) { + if (arguments.size() < 2 || arguments.get(1) == null) { throw new IllegalArgumentException(String.format("Could not resolve id type of %s!", repositoryInterface)); } - return (Class) arguments[1]; + return (Class) arguments.get(1).getType(); } private Class resolveDomainType(Class repositoryInterface) { - Class[] arguments = resolveTypeArguments(repositoryInterface, Repository.class); + TypeInformation information = ClassTypeInformation.from(repositoryInterface); + List> arguments = information.getSuperTypeInformation(Repository.class).getTypeArguments(); - if (arguments == null || arguments[0] == null) { + if (arguments.isEmpty() || arguments.get(0) == null) { throw new IllegalArgumentException(String.format("Could not resolve domain type of %s!", repositoryInterface)); } - return arguments[0]; + return arguments.get(0).getType(); } } diff --git a/src/test/java/org/springframework/data/repository/core/support/DefaultRepositoryMetadataUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/DefaultRepositoryMetadataUnitTests.java index 0bea9f298..021142ed6 100644 --- a/src/test/java/org/springframework/data/repository/core/support/DefaultRepositoryMetadataUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/DefaultRepositoryMetadataUnitTests.java @@ -15,6 +15,7 @@ */ package org.springframework.data.repository.core.support; +import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import java.io.Serializable; @@ -101,6 +102,18 @@ public class DefaultRepositoryMetadataUnitTests { assertEquals(Long.class, metadata.getIdType()); } + /** + * @see DATACMNS-501 + */ + @Test + public void discoversDomainAndIdTypeForIntermediateRepository() { + + RepositoryMetadata metadata = new DefaultRepositoryMetadata(IdTypeFixingRepository.class); + + assertThat(metadata.getDomainType(), is(typeCompatibleWith(Object.class))); + assertThat(metadata.getIdType(), is(typeCompatibleWith(Long.class))); + } + @SuppressWarnings("unused") private class User {