From b0348e272a02ede8524709cdeaf94161b6ccebaf Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Thu, 19 Mar 2020 10:12:45 +0100 Subject: [PATCH] #321 - Bind only bindable query method parameters. We now only bind parameters to the query that are actually bindable instead of consuming the entire parameter list. --- .../ExpressionEvaluatingParameterBinder.java | 5 ++--- .../query/StringBasedR2dbcQueryUnitTests.java | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/springframework/data/r2dbc/repository/query/ExpressionEvaluatingParameterBinder.java b/src/main/java/org/springframework/data/r2dbc/repository/query/ExpressionEvaluatingParameterBinder.java index c940628e..2306d4ca 100644 --- a/src/main/java/org/springframework/data/r2dbc/repository/query/ExpressionEvaluatingParameterBinder.java +++ b/src/main/java/org/springframework/data/r2dbc/repository/query/ExpressionEvaluatingParameterBinder.java @@ -110,13 +110,12 @@ class ExpressionEvaluatingParameterBinder { Parameters bindableParameters) { T bindSpecToUse = bindSpec; - int index = 0; int bindingIndex = 0; - for (Object value : values) { - Parameter bindableParameter = bindableParameters.getBindableParameter(index++); + for (Parameter bindableParameter : bindableParameters) { + Object value = values[bindableParameter.getIndex()]; Optional name = bindableParameter.getName(); if ((name.isPresent() && isNamedParameterUsed(name)) || !expressionQuery.getBindings().isEmpty()) { diff --git a/src/test/java/org/springframework/data/r2dbc/repository/query/StringBasedR2dbcQueryUnitTests.java b/src/test/java/org/springframework/data/r2dbc/repository/query/StringBasedR2dbcQueryUnitTests.java index efb4ed3a..7cde0801 100644 --- a/src/test/java/org/springframework/data/r2dbc/repository/query/StringBasedR2dbcQueryUnitTests.java +++ b/src/test/java/org/springframework/data/r2dbc/repository/query/StringBasedR2dbcQueryUnitTests.java @@ -27,6 +27,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.data.domain.Sort; import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.data.r2dbc.convert.MappingR2dbcConverter; @@ -221,6 +222,21 @@ public class StringBasedR2dbcQueryUnitTests { verifyNoMoreInteractions(bindSpec); } + @Test // gh-321 + public void skipsNonBindableParameters() { + + StringBasedR2dbcQuery query = getQueryMethod("queryWithUnusedParameter", String.class, Sort.class); + R2dbcParameterAccessor accessor = new R2dbcParameterAccessor(query.getQueryMethod(), "Walter", null); + + BindableQuery stringQuery = query.createQuery(accessor); + + assertThat(stringQuery.get()).isEqualTo("SELECT * FROM person WHERE lastname = :name"); + assertThat(stringQuery.bind(bindSpec)).isNotNull(); + + verify(bindSpec).bind(0, "Walter"); + verifyNoMoreInteractions(bindSpec); + } + private StringBasedR2dbcQuery getQueryMethod(String name, Class... args) { Method method = ReflectionUtils.findMethod(SampleRepository.class, name, args); @@ -263,6 +279,9 @@ public class StringBasedR2dbcQueryUnitTests { @Query("SELECT * FROM person WHERE lastname = :#{#person.name}") Person queryWithSpelObject(@Param("person") Person person); + + @Query("SELECT * FROM person WHERE lastname = :name") + Person queryWithUnusedParameter(String name, Sort unused); } static class Person {