From 7fb58c3c474bdc6a96244bcf880cbb9c4c13ff9f Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Wed, 7 Oct 2015 19:39:37 +0200 Subject: [PATCH] DATAJPA-809 - ParameterBinder now uses ParameterAccessor. We now use a ParameterAccessor to obtain query method parameters in ParameterBinder to benefit from value post-processing (e.g. unwrapping of Optional etc.). Related tickets: DATACMNS-768. --- .../jpa/repository/query/ParameterBinder.java | 43 ++++++------------- .../query/ParameterBinderUnitTests.java | 24 +++++++++-- 2 files changed, 33 insertions(+), 34 deletions(-) diff --git a/src/main/java/org/springframework/data/jpa/repository/query/ParameterBinder.java b/src/main/java/org/springframework/data/jpa/repository/query/ParameterBinder.java index 2d4f386505..f78ff8847d 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/ParameterBinder.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/ParameterBinder.java @@ -22,7 +22,9 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.jpa.repository.query.JpaParameters.JpaParameter; +import org.springframework.data.repository.query.ParameterAccessor; import org.springframework.data.repository.query.Parameters; +import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.util.Assert; /** @@ -35,6 +37,7 @@ public class ParameterBinder { private final JpaParameters parameters; + private final ParameterAccessor accessor; private final Object[] values; /** @@ -52,6 +55,7 @@ public ParameterBinder(JpaParameters parameters, Object[] values) { this.parameters = parameters; this.values = values.clone(); + this.accessor = new ParametersParameterAccessor(parameters, this.values); } ParameterBinder(JpaParameters parameters) { @@ -64,12 +68,7 @@ public ParameterBinder(JpaParameters parameters, Object[] values) { * @return */ public Pageable getPageable() { - - if (!parameters.hasPageableParameter()) { - return null; - } - - return (Pageable) values[parameters.getPageableIndex()]; + return accessor.getPageable(); } /** @@ -79,16 +78,7 @@ public Pageable getPageable() { * @return */ public Sort getSort() { - - if (parameters.hasSortParameter()) { - return (Sort) values[parameters.getSortIndex()]; - } - - if (parameters.hasPageableParameter() && getPageable() != null) { - return getPageable().getSort(); - } - - return null; + return accessor.getSort(); } /** @@ -99,19 +89,17 @@ public Sort getSort() { */ public T bind(T query) { - int methodParameterPosition = 0; + int bindableParameterIndex = 0; int queryParameterPosition = 1; for (JpaParameter parameter : parameters) { if (canBindParameter(parameter)) { - Object value = values[methodParameterPosition]; - + Object value = accessor.getBindableValue(bindableParameterIndex); bind(query, parameter, value, queryParameterPosition++); + bindableParameterIndex++; } - - methodParameterPosition++; } return query; @@ -181,15 +169,6 @@ private Query bindAndPrepare(Query query, Parameters parameters) { return result; } - /** - * Returns the values to bind. - * - * @return - */ - Object[] getValues() { - return values; - } - /** * Returns the parameters. * @@ -198,4 +177,8 @@ Object[] getValues() { JpaParameters getParameters() { return parameters; } + + protected Object[] getValues() { + return values; + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/query/ParameterBinderUnitTests.java b/src/test/java/org/springframework/data/jpa/repository/query/ParameterBinderUnitTests.java index 36148b229d..3f8c784da1 100644 --- a/src/test/java/org/springframework/data/jpa/repository/query/ParameterBinderUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/query/ParameterBinderUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2014 the original author or authors. + * Copyright 2008-2015 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. @@ -24,6 +24,7 @@ import java.lang.reflect.Method; import java.util.Date; import java.util.List; +import java.util.Optional; import javax.persistence.Embeddable; import javax.persistence.Query; @@ -86,6 +87,8 @@ static interface SampleRepository { User invalidWithTemporalTypeParameter(@Temporal String registerDate); List validWithVarArgs(Integer... ids); + + User optionalParameter(Optional name); } @Test(expected = IllegalArgumentException.class) @@ -174,8 +177,8 @@ public void bindsEmbeddableCorrectly() throws Exception { public void bindsSortForIndexedParameters() throws Exception { Sort sort = new Sort("name"); - ParameterBinder binder = new ParameterBinder(new JpaParameters(indexedParametersWithSort), new Object[] { "name", - sort }); + ParameterBinder binder = new ParameterBinder(new JpaParameters(indexedParametersWithSort), + new Object[] { "name", sort }); assertThat(binder.getSort(), is(sort)); } @@ -223,7 +226,6 @@ public void shouldThrowIllegalArgumentExceptionIfIsAnnotatedWithTemporalParamAnd /** * @see DATAJPA-461 - * @throws Exception */ @Test public void shouldAllowBindingOfVarArgsAsIs() throws Exception { @@ -236,6 +238,20 @@ public void shouldAllowBindingOfVarArgsAsIs() throws Exception { verify(query).setParameter(eq(1), eq(ids)); } + /** + * @see DATAJPA-809 + */ + @Test + public void unwrapsOptionalParameter() throws Exception { + + Method method = SampleRepository.class.getMethod("optionalParameter", Optional.class); + JpaParameters parameters = new JpaParameters(method); + + new ParameterBinder(parameters, new Object[] { Optional.of("Foo") }).bind(query); + + verify(query).setParameter(eq(1), eq("Foo")); + } + public SampleEntity findByEmbeddable(SampleEmbeddable embeddable) { return null;