Support Contains with ElementCollection of type String.

Properly handle `contains` for an ElementCollection of type String in a LIKE query, wrapping the the parameter in wildcards only when needed.

Closes: #2607.
This commit is contained in:
Jens Schauder
2022-08-01 14:37:03 +02:00
committed by Greg L. Turnquist
parent 525cf6abb0
commit 2a1f6e383e
2 changed files with 27 additions and 2 deletions

View File

@@ -15,7 +15,12 @@
*/
package org.springframework.data.jpa.repository.query;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Collectors;
@@ -192,6 +197,7 @@ class ParameterMetadataProvider {
private final ParameterExpression<T> expression;
private final EscapeCharacter escape;
private final boolean ignoreCase;
private final boolean noWildcards;
/**
* Creates a new {@link ParameterMetadata}.
@@ -202,6 +208,7 @@ class ParameterMetadataProvider {
this.expression = expression;
this.type = value == null && Type.SIMPLE_PROPERTY.equals(part.getType()) ? Type.IS_NULL : part.getType();
this.ignoreCase = IgnoreCaseType.ALWAYS.equals(part.shouldIgnoreCase());
this.noWildcards = part.getProperty().getLeafProperty().isCollection();
this.escape = escape;
}
@@ -237,7 +244,7 @@ class ParameterMetadataProvider {
return condensedValue;
}
if (String.class.equals(expression.getJavaType())) {
if (String.class.equals(expression.getJavaType()) && !noWildcards) {
switch (type) {
case STARTING_WITH:

View File

@@ -2829,6 +2829,24 @@ public class UserRepositoryTests {
.map(User::getAge).contains(30);
}
@Test // GH-2607
void containsWithCollection() {
firstUser.getAttributes().add("cool");
firstUser.getAttributes().add("hip");
secondUser.getAttributes().add("hip");
thirdUser.getAttributes().add("rockstar");
thirdUser.getAttributes().add("%hip%");
flushTestUsers();
List<User> result = repository.findByAttributesContains("hip");
assertThat(result).containsOnly(firstUser, secondUser);
}
private Page<User> executeSpecWithSort(Sort sort) {
flushTestUsers();