DATAJPA-1179 - Create multiple placeholders for duplicate SpELs.

Before a duplicate SpEL created one placeholder but multiple bindings resulting in exceptions during parameter binding.
This commit is contained in:
Jens Schauder
2017-09-18 10:18:43 +02:00
committed by Oliver Gierke
parent 3fce260e75
commit e403796e8a
4 changed files with 40 additions and 1 deletions

View File

@@ -243,7 +243,7 @@ class StringQuery {
}
if (replacement != null) {
result = StringUtils.replace(result, matcher.group(2), replacement);
result = replaceFirst(result, matcher.group(2), replacement);
}
}
@@ -251,6 +251,16 @@ class StringQuery {
return result;
}
private static String replaceFirst(String text, String substring, String replacement) {
int index = text.indexOf(substring);
if (index < 0) {
return text;
}
return text.substring(0, index) + replacement + text.substring(index + substring.length());
}
private int tryFindGreatestParameterIndexIn(String query) {
Matcher parameterIndexMatcher = PARAMETER_BINDING_BY_INDEX.matcher(query);

View File

@@ -2065,6 +2065,16 @@ public class UserRepositoryTests {
assertThat(query.getParameters()).hasSize(2);
}
@Test // DATAJPA-1179
public void duplicateSpelsWorkAsIntended() {
flushTestUsers();
List<User> users = repository.findUsersByDuplicateSpel("Oliver");
assertThat(users).hasSize(1);
}
private Page<User> executeSpecWithSort(Sort sort) {
flushTestUsers();

View File

@@ -33,6 +33,7 @@ import org.springframework.data.repository.query.parser.Part.Type;
*
* @author Oliver Gierke
* @author Thomas Darimont
* @author Jens Schauder
*/
public class StringQueryUnitTests {
@@ -291,6 +292,20 @@ public class StringQueryUnitTests {
assertThat(new StringQuery("select new Dto from A a").hasConstructorExpression(), is(false));
}
@Test // DATAJPA-1179
public void bindingsMatchQueryForIdenticalSpelExpressions() {
StringQuery query = new StringQuery("select a from A a where a.first = :#{#exp} or a.second = :#{#exp}");
List<ParameterBinding> bindings = query.getParameterBindings();
assertThat(bindings, not(empty()));
for (ParameterBinding binding : bindings) {
assertThat(binding.getName(), notNullValue());
assertThat(query.getQueryString(), containsString(binding.getName()));
}
}
private void assertPositionalBinding(Class<? extends ParameterBinding> bindingType, Integer position,
ParameterBinding expectedBinding) {

View File

@@ -489,6 +489,10 @@ public interface UserRepository
// DATAJPA-858
List<User> findByRolesNameContaining(String name);
// DATAJPA-1179
@Query("select u from User u where u.firstname = :#{#firstname} and u.firstname = :#{#firstname}")
List<User> findUsersByDuplicateSpel(@Param("firstname") String firstname);
List<RolesAndFirstname> findRolesAndFirstnameBy();
// DATAJPA-1172