DATAJPA-461 - Fixed regression in parameter binding of arrays.
Enhanced binding of parameters in StringQueryParameterBinder to be able to deal with situations where a parameter value has to be converted to be correctly bound e.g. for parameter values in IN-expressions. We now only convert array values to collections if the value is to be bound in the context of an IN-parameter. Previously we erroneously always converted an array value to a collection value which lead to problems if an array value was meant to be used "as-is" e.g. in cases where an user wants to query for a certain byte[]. Original pull request: #56.
This commit is contained in:
committed by
Oliver Gierke
parent
c85caf00d4
commit
f8b0917c90
@@ -1212,6 +1212,34 @@ public class UserRepositoryTests {
|
||||
assertThat(result, hasItem(firstUser));
|
||||
}
|
||||
|
||||
/**
|
||||
* @DATAJPA-461
|
||||
*/
|
||||
@Test
|
||||
public void customFindByQueryWithPositionalVarargsParameters() {
|
||||
|
||||
flushTestUsers();
|
||||
|
||||
Collection<User> result = repository.findByIdsCustomWithPositionalVarArgs(firstUser.getId(), secondUser.getId());
|
||||
|
||||
assertThat(result, hasSize(2));
|
||||
assertThat(result, hasItems(firstUser, secondUser));
|
||||
}
|
||||
|
||||
/**
|
||||
* @DATAJPA-461
|
||||
*/
|
||||
@Test
|
||||
public void customFindByQueryWithNamedVarargsParameters() {
|
||||
|
||||
flushTestUsers();
|
||||
|
||||
Collection<User> result = repository.findByIdsCustomWithNamedVarArgs(firstUser.getId(), secondUser.getId());
|
||||
|
||||
assertThat(result, hasSize(2));
|
||||
assertThat(result, hasItems(firstUser, secondUser));
|
||||
}
|
||||
|
||||
private Page<User> executeSpecWithSort(Sort sort) {
|
||||
|
||||
flushTestUsers();
|
||||
|
||||
@@ -19,7 +19,7 @@ import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.jpa.repository.query.StringQuery.LikeBinding;
|
||||
import org.springframework.data.jpa.repository.query.StringQuery.LikeParameterBinding;
|
||||
import org.springframework.data.repository.query.parser.Part.Type;
|
||||
|
||||
/**
|
||||
@@ -29,33 +29,33 @@ public class LikeBindingUnitTests {
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsNullName() {
|
||||
new LikeBinding(null, Type.CONTAINING);
|
||||
new LikeParameterBinding(null, Type.CONTAINING);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsEmptyName() {
|
||||
new LikeBinding("", Type.CONTAINING);
|
||||
new LikeParameterBinding("", Type.CONTAINING);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsNullType() {
|
||||
new LikeBinding("foo", null);
|
||||
new LikeParameterBinding("foo", null);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsInvalidType() {
|
||||
new LikeBinding("foo", Type.SIMPLE_PROPERTY);
|
||||
new LikeParameterBinding("foo", Type.SIMPLE_PROPERTY);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsInvalidPosition() {
|
||||
new LikeBinding(0, Type.CONTAINING);
|
||||
new LikeParameterBinding(0, Type.CONTAINING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setsUpInstanceForName() {
|
||||
|
||||
LikeBinding binding = new LikeBinding("foo", Type.CONTAINING);
|
||||
LikeParameterBinding binding = new LikeParameterBinding("foo", Type.CONTAINING);
|
||||
|
||||
assertThat(binding.hasName("foo"), is(true));
|
||||
assertThat(binding.hasName("bar"), is(false));
|
||||
@@ -67,7 +67,7 @@ public class LikeBindingUnitTests {
|
||||
@Test
|
||||
public void setsUpInstanceForIndex() {
|
||||
|
||||
LikeBinding binding = new LikeBinding(1, Type.CONTAINING);
|
||||
LikeParameterBinding binding = new LikeParameterBinding(1, Type.CONTAINING);
|
||||
|
||||
assertThat(binding.hasName("foo"), is(false));
|
||||
assertThat(binding.hasName(null), is(false));
|
||||
@@ -83,12 +83,12 @@ public class LikeBindingUnitTests {
|
||||
assertAugmentedValue(Type.ENDING_WITH, "%value");
|
||||
assertAugmentedValue(Type.STARTING_WITH, "value%");
|
||||
|
||||
assertThat(new LikeBinding(1, Type.CONTAINING).prepare(null), is(nullValue()));
|
||||
assertThat(new LikeParameterBinding(1, Type.CONTAINING).prepare(null), is(nullValue()));
|
||||
}
|
||||
|
||||
private static void assertAugmentedValue(Type type, Object value) {
|
||||
|
||||
LikeBinding binding = new LikeBinding("foo", type);
|
||||
LikeParameterBinding binding = new LikeParameterBinding("foo", type);
|
||||
assertThat(binding.prepare("value"), is(value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008-2013 the original author or authors.
|
||||
* Copyright 2008-2014 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.
|
||||
@@ -22,7 +22,6 @@ import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@@ -223,18 +222,18 @@ public class ParameterBinderUnitTests {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-415
|
||||
* @see DATAJPA-461
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void shouldAllowBindingOfVarArgs() throws Exception {
|
||||
public void shouldAllowBindingOfVarArgsAsIs() throws Exception {
|
||||
|
||||
Method method = SampleRepository.class.getMethod("validWithVarArgs", Integer[].class);
|
||||
JpaParameters parameters = new JpaParameters(method);
|
||||
Integer[] ids = new Integer[] { 1, 2, 3 };
|
||||
new ParameterBinder(parameters, new Object[] { ids }).bind(query);
|
||||
|
||||
verify(query).setParameter(eq(1), eq(Arrays.asList(1, 2, 3)));
|
||||
verify(query).setParameter(eq(1), eq(ids));
|
||||
}
|
||||
|
||||
public SampleEntity findByEmbeddable(SampleEmbeddable embeddable) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
* Copyright 2013-2014 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.
|
||||
@@ -21,7 +21,9 @@ import static org.junit.Assert.*;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.jpa.repository.query.StringQuery.LikeBinding;
|
||||
import org.springframework.data.jpa.repository.query.StringQuery.InParameterBinding;
|
||||
import org.springframework.data.jpa.repository.query.StringQuery.LikeParameterBinding;
|
||||
import org.springframework.data.jpa.repository.query.StringQuery.ParameterBinding;
|
||||
import org.springframework.data.repository.query.parser.Part.Type;
|
||||
|
||||
/**
|
||||
@@ -41,13 +43,13 @@ public class StringQueryUnitTests {
|
||||
String source = "select from User u where u.firstname like :firstname";
|
||||
StringQuery query = new StringQuery(source);
|
||||
|
||||
assertThat(query.hasLikeBindings(), is(true));
|
||||
assertThat(query.hasParameterBindings(), is(true));
|
||||
assertThat(query.getQueryString(), is(source));
|
||||
|
||||
List<LikeBinding> bindings = query.getLikeBindings();
|
||||
List<ParameterBinding> bindings = query.getParameterBindings();
|
||||
assertThat(bindings, hasSize(1));
|
||||
|
||||
LikeBinding binding = bindings.get(0);
|
||||
LikeParameterBinding binding = (LikeParameterBinding) bindings.get(0);
|
||||
assertThat(binding.getType(), is(Type.LIKE));
|
||||
assertThat(binding.hasName("firstname"), is(true));
|
||||
}
|
||||
@@ -57,18 +59,18 @@ public class StringQueryUnitTests {
|
||||
|
||||
StringQuery query = new StringQuery("select u from User u where u.firstname like %?1% or u.lastname like %?2");
|
||||
|
||||
assertThat(query.hasLikeBindings(), is(true));
|
||||
assertThat(query.hasParameterBindings(), is(true));
|
||||
assertThat(query.getQueryString(), is("select u from User u where u.firstname like ?1 or u.lastname like ?2"));
|
||||
|
||||
List<LikeBinding> bindings = query.getLikeBindings();
|
||||
List<ParameterBinding> bindings = query.getParameterBindings();
|
||||
assertThat(bindings, hasSize(2));
|
||||
|
||||
LikeBinding binding = bindings.get(0);
|
||||
LikeParameterBinding binding = (LikeParameterBinding) bindings.get(0);
|
||||
assertThat(binding, is(notNullValue()));
|
||||
assertThat(binding.hasPosition(1), is(true));
|
||||
assertThat(binding.getType(), is(Type.CONTAINING));
|
||||
|
||||
binding = bindings.get(1);
|
||||
binding = (LikeParameterBinding) bindings.get(1);
|
||||
assertThat(binding, is(notNullValue()));
|
||||
assertThat(binding.hasPosition(2), is(true));
|
||||
assertThat(binding.getType(), is(Type.ENDING_WITH));
|
||||
@@ -79,18 +81,92 @@ public class StringQueryUnitTests {
|
||||
|
||||
StringQuery query = new StringQuery("select u from User u where u.firstname like %:firstname");
|
||||
|
||||
assertThat(query.hasLikeBindings(), is(true));
|
||||
assertThat(query.hasParameterBindings(), is(true));
|
||||
assertThat(query.getQueryString(), is("select u from User u where u.firstname like :firstname"));
|
||||
|
||||
List<LikeBinding> bindings = query.getLikeBindings();
|
||||
List<ParameterBinding> bindings = query.getParameterBindings();
|
||||
assertThat(bindings, hasSize(1));
|
||||
|
||||
LikeBinding binding = bindings.get(0);
|
||||
LikeParameterBinding binding = (LikeParameterBinding) bindings.get(0);
|
||||
assertThat(binding, is(notNullValue()));
|
||||
assertThat(binding.hasName("firstname"), is(true));
|
||||
assertThat(binding.getType(), is(Type.ENDING_WITH));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-461
|
||||
*/
|
||||
@Test
|
||||
public void detectsNamedInParameterBindings() {
|
||||
|
||||
String queryString = "select u from User u where u.id in :ids";
|
||||
StringQuery query = new StringQuery(queryString);
|
||||
|
||||
assertThat(query.hasParameterBindings(), is(true));
|
||||
assertThat(query.getQueryString(), is(queryString));
|
||||
|
||||
List<ParameterBinding> bindings = query.getParameterBindings();
|
||||
assertThat(bindings, hasSize(1));
|
||||
|
||||
assertNamedBinding(InParameterBinding.class, "ids", bindings.get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-461
|
||||
*/
|
||||
@Test
|
||||
public void detectsMultipleNamedInParameterBindings() {
|
||||
|
||||
String queryString = "select u from User u where u.id in :ids and u.name in :names and foo = :bar";
|
||||
StringQuery query = new StringQuery(queryString);
|
||||
|
||||
assertThat(query.hasParameterBindings(), is(true));
|
||||
assertThat(query.getQueryString(), is(queryString));
|
||||
|
||||
List<ParameterBinding> bindings = query.getParameterBindings();
|
||||
assertThat(bindings, hasSize(2));
|
||||
|
||||
assertNamedBinding(InParameterBinding.class, "ids", bindings.get(0));
|
||||
assertNamedBinding(InParameterBinding.class, "names", bindings.get(1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-461
|
||||
*/
|
||||
@Test
|
||||
public void detectsPositionalInParameterBindings() {
|
||||
|
||||
String queryString = "select u from User u where u.id in ?1";
|
||||
StringQuery query = new StringQuery(queryString);
|
||||
|
||||
assertThat(query.hasParameterBindings(), is(true));
|
||||
assertThat(query.getQueryString(), is(queryString));
|
||||
|
||||
List<ParameterBinding> bindings = query.getParameterBindings();
|
||||
assertThat(bindings, hasSize(1));
|
||||
|
||||
assertPositionalBinding(InParameterBinding.class, 1, bindings.get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-461
|
||||
*/
|
||||
@Test
|
||||
public void detectsMultiplePositionalInParameterBindings() {
|
||||
|
||||
String queryString = "select u from User u where u.id in ?1 and u.names in ?2 and foo = ?3";
|
||||
StringQuery query = new StringQuery(queryString);
|
||||
|
||||
assertThat(query.hasParameterBindings(), is(true));
|
||||
assertThat(query.getQueryString(), is(queryString));
|
||||
|
||||
List<ParameterBinding> bindings = query.getParameterBindings();
|
||||
assertThat(bindings, hasSize(2));
|
||||
|
||||
assertPositionalBinding(InParameterBinding.class, 1, bindings.get(0));
|
||||
assertPositionalBinding(InParameterBinding.class, 2, bindings.get(1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-373
|
||||
*/
|
||||
@@ -103,4 +179,20 @@ public class StringQueryUnitTests {
|
||||
public void rejectsDifferentBindingsForRepeatedParameter() {
|
||||
new StringQuery("select u from User u where u.firstname like %?1 and u.lastname like ?1%");
|
||||
}
|
||||
|
||||
private void assertPositionalBinding(Class<? extends ParameterBinding> bindingType, Integer position,
|
||||
ParameterBinding expectedBinding) {
|
||||
|
||||
assertThat(bindingType.isInstance(expectedBinding), is(true));
|
||||
assertThat(expectedBinding, is(notNullValue()));
|
||||
assertThat(expectedBinding.hasPosition(position), is(true));
|
||||
}
|
||||
|
||||
private void assertNamedBinding(Class<? extends ParameterBinding> bindingType, String parameterName,
|
||||
ParameterBinding expectedBinding) {
|
||||
|
||||
assertThat(bindingType.isInstance(expectedBinding), is(true));
|
||||
assertThat(expectedBinding, is(notNullValue()));
|
||||
assertThat(expectedBinding.hasName(parameterName), is(true));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008-2013 the original author or authors.
|
||||
* Copyright 2008-2014 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.
|
||||
@@ -277,6 +277,18 @@ public interface UserRepository extends JpaRepository<User, Integer>, JpaSpecifi
|
||||
*/
|
||||
Collection<User> findByIdIn(@Param("ids") Integer... ids);
|
||||
|
||||
/**
|
||||
* @see DATAJPA-461
|
||||
*/
|
||||
@Query("select u from User u where u.id in ?1")
|
||||
Collection<User> findByIdsCustomWithPositionalVarArgs(Integer... ids);
|
||||
|
||||
/**
|
||||
* @see DATAJPA-461
|
||||
*/
|
||||
@Query("select u from User u where u.id in :ids")
|
||||
Collection<User> findByIdsCustomWithNamedVarArgs(@Param("ids") Integer... ids);
|
||||
|
||||
/**
|
||||
* @see DATAJPA-415
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user