diff --git a/src/main/java/org/springframework/data/jpa/repository/query/ParameterMetadataProvider.java b/src/main/java/org/springframework/data/jpa/repository/query/ParameterMetadataProvider.java index 5fe789945..644f36a9c 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/ParameterMetadataProvider.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/ParameterMetadataProvider.java @@ -61,7 +61,6 @@ class ParameterMetadataProvider { */ public ParameterMetadataProvider(CriteriaBuilder builder, ParametersParameterAccessor accessor, PersistenceProvider provider) { - this(builder, accessor.iterator(), accessor.getParameters(), provider); } @@ -121,7 +120,7 @@ class ParameterMetadataProvider { public ParameterMetadata next(Part part) { Parameter parameter = parameters.next(); - return (ParameterMetadata) next(part, parameter.getType(), parameter.getName()); + return (ParameterMetadata) next(part, parameter.getType(), parameter); } /** @@ -137,7 +136,7 @@ class ParameterMetadataProvider { Parameter parameter = parameters.next(); Class typeToUse = ClassUtils.isAssignable(type, parameter.getType()) ? parameter.getType() : type; - return (ParameterMetadata) next(part, typeToUse, null); + return (ParameterMetadata) next(part, typeToUse, parameter); } /** @@ -149,7 +148,7 @@ class ParameterMetadataProvider { * @param name * @return */ - private ParameterMetadata next(Part part, Class type, String name) { + private ParameterMetadata next(Part part, Class type, Parameter parameter) { Assert.notNull(type); @@ -159,8 +158,8 @@ class ParameterMetadataProvider { @SuppressWarnings("unchecked") Class reifiedType = Expression.class.equals(type) ? (Class) Object.class : type; - ParameterExpression expression = name == null ? builder.parameter(reifiedType) : builder.parameter(reifiedType, - name); + ParameterExpression expression = parameter.isExplicitlyNamed() + ? builder.parameter(reifiedType, parameter.getName()) : builder.parameter(reifiedType); ParameterMetadata value = new ParameterMetadata(expression, part.getType(), bindableParameterValues == null ? ParameterMetadata.PLACEHOLDER : bindableParameterValues.next(), this.persistenceProvider); @@ -233,8 +232,8 @@ class ParameterMetadataProvider { case CONTAINING: return String.format("%%%s%%", value.toString()); default: - return Collection.class.isAssignableFrom(expression.getJavaType()) ? persistenceProvider - .potentiallyConvertEmptyCollection(toCollection(value)) : value; + return Collection.class.isAssignableFrom(expression.getJavaType()) + ? persistenceProvider.potentiallyConvertEmptyCollection(toCollection(value)) : value; } } diff --git a/src/test/java/org/springframework/data/jpa/repository/query/EclipseLinkParameterMetadataProviderIntegrationTests.java b/src/test/java/org/springframework/data/jpa/repository/query/EclipseLinkParameterMetadataProviderIntegrationTests.java new file mode 100644 index 000000000..a5208e150 --- /dev/null +++ b/src/test/java/org/springframework/data/jpa/repository/query/EclipseLinkParameterMetadataProviderIntegrationTests.java @@ -0,0 +1,27 @@ +/* + * Copyright 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jpa.repository.query; + +import org.springframework.test.context.ContextConfiguration; + +/** + * EclipseLink-specific tests for {@link ParameterMetadataProvider}. + * + * @author Oliver Gierke + * @soundtrack Elephants Crossing - We are (Irrelephant) + */ +@ContextConfiguration("classpath:eclipselink.xml") +public class EclipseLinkParameterMetadataProviderIntegrationTests extends ParameterMetadataProviderIntegrationTests {} diff --git a/src/test/java/org/springframework/data/jpa/repository/query/OpenJpaParameterMetadataProviderIntegrationTests.java b/src/test/java/org/springframework/data/jpa/repository/query/OpenJpaParameterMetadataProviderIntegrationTests.java new file mode 100644 index 000000000..c02130307 --- /dev/null +++ b/src/test/java/org/springframework/data/jpa/repository/query/OpenJpaParameterMetadataProviderIntegrationTests.java @@ -0,0 +1,27 @@ +/* + * Copyright 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jpa.repository.query; + +import org.springframework.test.context.ContextConfiguration; + +/** + * OpenJpa-specific tests for {@link ParameterMetadataProvider}. + * + * @author Oliver Gierke + * @soundtrack Elephants Crossing - We are (Irrelephant) + */ +@ContextConfiguration("classpath:openjpa.xml") +public class OpenJpaParameterMetadataProviderIntegrationTests extends ParameterMetadataProviderIntegrationTests {} diff --git a/src/test/java/org/springframework/data/jpa/repository/query/ParameterMetadataProviderIntegrationTests.java b/src/test/java/org/springframework/data/jpa/repository/query/ParameterMetadataProviderIntegrationTests.java new file mode 100644 index 000000000..38d46746a --- /dev/null +++ b/src/test/java/org/springframework/data/jpa/repository/query/ParameterMetadataProviderIntegrationTests.java @@ -0,0 +1,98 @@ +/* + * Copyright 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jpa.repository.query; + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.*; + +import java.lang.reflect.Method; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.data.jpa.domain.sample.User; +import org.springframework.data.jpa.provider.PersistenceProvider; +import org.springframework.data.jpa.repository.query.ParameterMetadataProvider.ParameterMetadata; +import org.springframework.data.repository.query.Param; +import org.springframework.data.repository.query.Parameters; +import org.springframework.data.repository.query.parser.Part; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.util.ReflectionTestUtils; + +/** + * Integration tests for {@link ParameterMetadataProvider}. + * + * @author Oliver Gierke + * @soundtrack Elephants Crossing - We are (Irrelephant) + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:infrastructure.xml") +public class ParameterMetadataProviderIntegrationTests { + + @PersistenceContext EntityManager em; + + /** + * @see DATAJPA-758 + */ + @Test + public void forwardsParameterNameIfTransparentlyNamed() throws Exception { + + ParameterMetadataProvider provider = createProvider(Sample.class.getMethod("findByFirstname", String.class)); + ParameterMetadata metadata = provider.next(new Part("firstname", User.class)); + + assertThat(metadata.getExpression().getName(), is("name")); + } + + /** + * @see DATAJPA-758 + */ + @Test + public void forwardsParameterNameIfExplicitlyAnnotated() throws Exception { + + ParameterMetadataProvider provider = createProvider(Sample.class.getMethod("findByLastname", String.class)); + ParameterMetadata metadata = provider.next(new Part("lastname", User.class)); + + assertThat(metadata.getExpression().getName(), is(nullValue())); + } + + private ParameterMetadataProvider createProvider(Method method) { + + JpaParameters parameters = new JpaParameters(method); + simulateDiscoveredParametername(parameters, 0, "name"); + + return new ParameterMetadataProvider(em.getCriteriaBuilder(), parameters, + PersistenceProvider.fromEntityManager(em)); + } + + @SuppressWarnings("unchecked") + private static void simulateDiscoveredParametername(Parameters parameters, int index, String name) { + + List list = (List) ReflectionTestUtils.getField(parameters, "parameters"); + Object parameter = ReflectionTestUtils.getField(list.get(0), "parameter"); + ReflectionTestUtils.setField(parameter, "parameterName", name); + } + + interface Sample { + + User findByFirstname(@Param("name") String firstname); + + User findByLastname(String lastname); + } +}