diff --git a/src/main/java/org/springframework/data/repository/core/support/DefaultRepositoryInformation.java b/src/main/java/org/springframework/data/repository/core/support/DefaultRepositoryInformation.java index c21d93510..7365d9f24 100644 --- a/src/main/java/org/springframework/data/repository/core/support/DefaultRepositoryInformation.java +++ b/src/main/java/org/springframework/data/repository/core/support/DefaultRepositoryInformation.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2015 the original author or authors. + * Copyright 2011-2016 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. @@ -342,26 +342,28 @@ class DefaultRepositoryInformation implements RepositoryInformation { */ private boolean parametersMatch(Method method, Method baseClassMethod) { + Class[] methodParameterTypes = method.getParameterTypes(); Type[] genericTypes = baseClassMethod.getGenericParameterTypes(); Class[] types = baseClassMethod.getParameterTypes(); for (int i = 0; i < genericTypes.length; i++) { - Type type = genericTypes[i]; + Type genericType = genericTypes[i]; + Class type = types[i]; MethodParameter parameter = new MethodParameter(method, i); Class parameterType = resolveParameterType(parameter, metadata.getRepositoryInterface()); - if (type instanceof TypeVariable) { - if (!matchesGenericType((TypeVariable) type, parameterType)) { - return false; - } - } else { - // We must either have an exact match, or, - if (!types[i].equals(parameterType) && - // the tpes must be assignable _and_ signature definition types must be identical. - !(types[i].isAssignableFrom(parameterType) && types[i].equals(method.getParameterTypes()[i]))) { + if (genericType instanceof TypeVariable) { + + if (!matchesGenericType((TypeVariable) genericType, parameterType)) { return false; } + + continue; + } + + if (!type.isAssignableFrom(parameterType) || !type.equals(methodParameterTypes[i])) { + return false; } } @@ -392,7 +394,7 @@ class DefaultRepositoryInformation implements RepositoryInformation { boolean isDomainTypeVariableReference = DOMAIN_TYPE_NAME.equals(referenceName); boolean parameterMatchesEntityType = parameterType.isAssignableFrom(entityType); - // We need this check to besure not to match save(Iterable) for entities implementing Iterable + // We need this check to be sure not to match save(Iterable) for entities implementing Iterable boolean isNotIterable = !parameterType.equals(Iterable.class); if (isDomainTypeVariableReference && parameterMatchesEntityType && isNotIterable) { diff --git a/src/test/java/org/springframework/data/repository/core/support/DefaultRepositoryInformationUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/DefaultRepositoryInformationUnitTests.java index d175b6d8f..2d017e46f 100644 --- a/src/test/java/org/springframework/data/repository/core/support/DefaultRepositoryInformationUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/DefaultRepositoryInformationUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-2016 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. @@ -94,22 +94,6 @@ public class DefaultRepositoryInformationUnitTests { assertThat(information.getTargetClassMethod(source), is(expected)); } - /** - * @see DATACMNS-854 - */ - @Test - public void discoversCustomlyImplementedCrudMethodWithGenerics() throws SecurityException, NoSuchMethodException { - - RepositoryMetadata metadata = new DefaultRepositoryMetadata(FooRepository.class); - RepositoryInformation information = new DefaultRepositoryInformation(metadata, CrudRepository.class, - customImplementation.getClass()); - - Method source = FooRepositoryCustom.class.getMethod("exists", Object.class); - Method expected = customImplementation.getClass().getMethod("exists", Object.class); - - assertThat(information.getTargetClassMethod(source), is(expected)); - } - @Test public void considersIntermediateMethodsAsFinderMethods() { @@ -239,12 +223,30 @@ public class DefaultRepositoryInformationUnitTests { } } - private Method getMethodFrom(Class type, String name) { + /** + * @see DATACMNS-854 + */ + @Test + public void discoversCustomlyImplementedCrudMethodWithGenerics() throws SecurityException, NoSuchMethodException { + + RepositoryMetadata metadata = new DefaultRepositoryMetadata(FooRepository.class); + RepositoryInformation information = new DefaultRepositoryInformation(metadata, CrudRepository.class, + customImplementation.getClass()); + + Method source = FooRepositoryCustom.class.getMethod("exists", Object.class); + Method expected = customImplementation.getClass().getMethod("exists", Object.class); + + assertThat(information.getTargetClassMethod(source), is(expected)); + } + + private static Method getMethodFrom(Class type, String name) { + for (Method method : type.getMethods()) { if (method.getName().equals(name)) { return method; } } + return null; } @@ -252,7 +254,6 @@ public class DefaultRepositoryInformationUnitTests { @Retention(RetentionPolicy.RUNTIME) @QueryAnnotation @interface MyQuery { - } interface FooRepository extends CrudRepository, FooRepositoryCustom {