diff --git a/src/main/java/org/springframework/data/repository/query/Parameter.java b/src/main/java/org/springframework/data/repository/query/Parameter.java index b90c84f05..42e36142a 100644 --- a/src/main/java/org/springframework/data/repository/query/Parameter.java +++ b/src/main/java/org/springframework/data/repository/query/Parameter.java @@ -22,8 +22,10 @@ import java.util.Arrays; import java.util.List; import org.springframework.core.MethodParameter; +import org.springframework.core.ResolvableType; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; +import org.springframework.data.repository.util.QueryExecutionConverters; import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; import org.springframework.util.Assert; @@ -41,6 +43,7 @@ public class Parameter { private static final String POSITION_PARAMETER_TEMPLATE = "?%s"; private final MethodParameter parameter; + private final Class parameterType; private final boolean isDynamicProjectionParameter; /** @@ -53,6 +56,7 @@ public class Parameter { Assert.notNull(parameter); this.parameter = parameter; + this.parameterType = potentiallyUnwrapParameterType(parameter); this.isDynamicProjectionParameter = isDynamicProjectionParameter(parameter); } @@ -133,7 +137,7 @@ public class Parameter { * @return the type */ public Class getType() { - return parameter.getParameterType(); + return parameterType; } /** @@ -199,4 +203,18 @@ public class Parameter { TypeInformation bound = parameterTypes.getTypeArguments().get(0); return bound.equals(returnType.getActualType()); } + + /** + * Returns the component type if the given {@link MethodParameter} is a wrapper type. + * + * @param parameter must not be {@literal null}. + * @return + */ + private static Class potentiallyUnwrapParameterType(MethodParameter parameter) { + + Class originalType = parameter.getParameterType(); + + return QueryExecutionConverters.supports(originalType) + ? ResolvableType.forMethodParameter(parameter).getGeneric(0).getRawClass() : originalType; + } } diff --git a/src/test/java/org/springframework/data/repository/query/ParametersUnitTests.java b/src/test/java/org/springframework/data/repository/query/ParametersUnitTests.java index 524f8d635..a73cac5d8 100644 --- a/src/test/java/org/springframework/data/repository/query/ParametersUnitTests.java +++ b/src/test/java/org/springframework/data/repository/query/ParametersUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2015 the original author or authors. + * Copyright 2008-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. You may obtain a copy of @@ -15,10 +15,11 @@ */ package org.springframework.data.repository.query; -import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import java.lang.reflect.Method; +import java.util.Optional; import org.junit.Before; import org.junit.Test; @@ -164,6 +165,17 @@ public class ParametersUnitTests { assertThat(parameters.getParameter(2).isDynamicProjectionParameter(), is(false)); } + /** + * @see DATACMNS-863 + */ + @Test + public void unwrapsOptionals() throws Exception { + + Parameters parameters = getParametersFor("methodWithOptional", Optional.class); + + assertThat(parameters.getParameter(0).getType(), is(typeCompatibleWith(String.class))); + } + private Parameters getParametersFor(String methodName, Class... parameterTypes) throws SecurityException, NoSuchMethodException { @@ -195,5 +207,7 @@ public class ParametersUnitTests { User emptyParameters(); T dynamicBind(Class type, Class one, Class two); + + void methodWithOptional(Optional optional); } }