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 48bcdac42..c21d93510 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 @@ -356,7 +356,10 @@ class DefaultRepositoryInformation implements RepositoryInformation { return false; } } else { - if (!types[i].equals(parameterType)) { + // 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]))) { return false; } } 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 78ab79074..d175b6d8f 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 @@ -94,6 +94,22 @@ 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() { @@ -248,8 +264,11 @@ public class DefaultRepositoryInformationUnitTests { User findOne(Long primaryKey); } - interface FooRepositoryCustom { + interface FooSuperInterfaceWithGenerics { + boolean exists(T id); + } + interface FooRepositoryCustom extends FooSuperInterfaceWithGenerics { User save(User user); }