Skip to content

Commit 21e62a6

Browse files
christophstroblmp911de
authored andcommitted
Relax query parameter validation.
This change allows to use collection/array arguments with scalar operators when targeting a collection like property. Closes #3356 Original pull request: #3359
1 parent 764a3ed commit 21e62a6

File tree

3 files changed

+33
-8
lines changed

3 files changed

+33
-8
lines changed

spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/PartTreeJpaQuery.java

+9-5
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,14 @@ private static void throwExceptionOnArgumentMismatch(String methodName, Part par
166166

167167
JpaParameter parameter = parameters.getBindableParameter(index);
168168

169-
if (expectsCollection(type) && !parameterIsCollectionLike(parameter)) {
170-
throw new IllegalStateException(wrongParameterTypeMessage(methodName, property, type, "Collection", parameter));
171-
} else if (!expectsCollection(type) && !parameterIsScalarLike(parameter)) {
172-
throw new IllegalStateException(wrongParameterTypeMessage(methodName, property, type, "scalar", parameter));
169+
if (expectsCollection(type)) {
170+
if (!parameterIsCollectionLike(parameter)) {
171+
throw new IllegalStateException(wrongParameterTypeMessage(methodName, property, type, "Collection", parameter));
172+
}
173+
} else {
174+
if (!part.getProperty().isCollection() && !parameterIsScalarLike(parameter)) {
175+
throw new IllegalStateException(wrongParameterTypeMessage(methodName, property, type, "scalar", parameter));
176+
}
173177
}
174178
}
175179

@@ -319,7 +323,7 @@ protected JpaQueryCreator createCreator(@Nullable JpaParametersParameterAccessor
319323
returnedType = processor.getReturnedType();
320324
}
321325

322-
if (accessor != null && accessor.getScrollPosition()instanceof KeysetScrollPosition keyset) {
326+
if (accessor != null && accessor.getScrollPosition() instanceof KeysetScrollPosition keyset) {
323327
return new JpaKeysetScrollQueryCreator(tree, returnedType, builder, provider, entityInformation, keyset);
324328
}
325329

spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java

+12-3
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,16 @@
3939
import java.lang.annotation.Annotation;
4040
import java.lang.reflect.AnnotatedElement;
4141
import java.lang.reflect.Member;
42-
import java.util.*;
42+
import java.util.ArrayList;
43+
import java.util.Collections;
44+
import java.util.HashMap;
45+
import java.util.HashSet;
46+
import java.util.Iterator;
47+
import java.util.List;
48+
import java.util.Locale;
49+
import java.util.Map;
50+
import java.util.Objects;
51+
import java.util.Set;
4352
import java.util.regex.Matcher;
4453
import java.util.regex.Pattern;
4554
import java.util.stream.Collectors;
@@ -568,7 +577,7 @@ public static <T> Query applyAndBind(String queryString, Iterable<T> entities, E
568577
*
569578
* @param originalQuery must not be {@literal null} or empty.
570579
* @return Guaranteed to be not {@literal null}.
571-
* @deprecated use {@link DeclaredQuery#deriveCountQuery(String, String)} instead.
580+
* @deprecated use {@link DeclaredQuery#deriveCountQuery(String)} instead.
572581
*/
573582
@Deprecated
574583
public static String createCountQueryFor(String originalQuery) {
@@ -582,7 +591,7 @@ public static String createCountQueryFor(String originalQuery) {
582591
* @param countProjection may be {@literal null}.
583592
* @return a query String to be used a count query for pagination. Guaranteed to be not {@literal null}.
584593
* @since 1.6
585-
* @deprecated use {@link DeclaredQuery#deriveCountQuery(String, String)} instead.
594+
* @deprecated use {@link DeclaredQuery#deriveCountQuery(String)} instead.
586595
*/
587596
@Deprecated
588597
public static String createCountQueryFor(String originalQuery, @Nullable String countProjection) {

spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/PartTreeJpaQueryIntegrationTests.java

+12
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import java.util.Collection;
3131
import java.util.Date;
3232
import java.util.List;
33+
import java.util.Set;
3334

3435
import org.hibernate.Version;
3536
import org.junit.jupiter.api.BeforeEach;
@@ -228,6 +229,13 @@ void errorsDueToMissingPropertyContainNameOfMethodAndInterface() throws Exceptio
228229
.withMessageContaining("UserRepository"); // the repository
229230
}
230231

232+
@Test // GH-3356
233+
void allowsCollectionArgForCollectionProperty() throws Exception {
234+
235+
new PartTreeJpaQuery(getQueryMethod("findByAttributes", Set.class), entityManager);
236+
new PartTreeJpaQuery(getQueryMethod("findByAttributes", String[].class), entityManager);
237+
}
238+
231239
private void testIgnoreCase(String methodName, Object... values) throws Exception {
232240

233241
Class<?>[] parameterTypes = new Class[values.length];
@@ -297,6 +305,10 @@ interface UserRepository extends Repository<User, Integer> {
297305

298306
// Wrong property name
299307
User findByNoSuchProperty(String x);
308+
309+
List<User> findByAttributes(Set<String> attributes);
310+
311+
List<User> findByAttributes(String... attributes);
300312
}
301313

302314
}

0 commit comments

Comments
 (0)