From e0006e21ae5917ea61bef47999d8ef01e2c5f119 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 | 12 +++++++++++ 2 files changed, 24 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 decdc781e..e66ee182b 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 @@ -129,6 +129,18 @@ public class DefaultRepositoryMetadataUnitTests { assertThat(metadata.getReturnedDomainClass(method), is(typeCompatibleWith(User.class))); } + /** + * @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 {