Browse Source

Unwrap nested collections in default Querydsl binding.

When binding values to collection-like paths, we now unwrap potentially double-wrapped collections as QuerydslPredicateBuilder attempts to convert the binding value to the type of the path.

Our default is a contains binding for single elements.

Closes #2834
pull/2841/head
Mark Paluch 3 years ago
parent
commit
bfcb2ffeae
No known key found for this signature in database
GPG Key ID: 4406B84C1661DCD1
  1. 11
      src/main/java/org/springframework/data/querydsl/binding/QuerydslDefaultBinding.java
  2. 14
      src/test/java/org/springframework/data/querydsl/binding/QuerydslDefaultBindingUnitTests.java
  3. 9
      src/test/java/org/springframework/data/querydsl/binding/QuerydslPredicateBuilderUnitTests.java

11
src/main/java/org/springframework/data/querydsl/binding/QuerydslDefaultBinding.java

@ -59,7 +59,16 @@ class QuerydslDefaultBinding implements MultiValueBinding<Path<? extends Object> @@ -59,7 +59,16 @@ class QuerydslDefaultBinding implements MultiValueBinding<Path<? extends Object>
BooleanBuilder builder = new BooleanBuilder();
for (Object element : value) {
builder.and(((CollectionPathBase) path).contains(element));
if (element instanceof Collection<?> nestedCollection) {
for (Object nested : nestedCollection) {
builder.and(((CollectionPathBase) path).contains(nested));
}
} else {
builder.and(((CollectionPathBase) path).contains(element));
}
}
return Optional.of(builder.getValue());

14
src/test/java/org/springframework/data/querydsl/binding/QuerydslDefaultBindingUnitTests.java

@ -22,13 +22,15 @@ import java.util.Collections; @@ -22,13 +22,15 @@ import java.util.Collections;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.data.querydsl.QUser;
/**
* Unit tests for {@link QuerydslDefaultBinding}.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @author Colin Gao
* @author Mark Paluch
*/
class QuerydslDefaultBindingUnitTests {
@ -64,6 +66,14 @@ class QuerydslDefaultBindingUnitTests { @@ -64,6 +66,14 @@ class QuerydslDefaultBindingUnitTests {
assertThat(predicate).hasValue(QUser.user.nickNames.contains("dragon reborn"));
}
@Test // GH-2834
void shouldUnwrapNestedCollectionsWithContainingWhenPropertyIsCollectionLike() {
var predicate = binding.bind(QUser.user.nickNames, Collections.singleton(Collections.singleton("dragon reborn")));
assertThat(predicate).hasValue(QUser.user.nickNames.contains("dragon reborn"));
}
@Test // DATACMNS-669
void shouldCreatePredicateWithInWhenPropertyIsAnObjectAndValueIsACollection() {
@ -73,7 +83,7 @@ class QuerydslDefaultBindingUnitTests { @@ -73,7 +83,7 @@ class QuerydslDefaultBindingUnitTests {
}
@Test
void testname() {
void shouldNotBindEmptyParameterCollection() {
assertThat(binding.bind(QUser.user.lastname, Collections.emptySet())).isNotPresent();
}

9
src/test/java/org/springframework/data/querydsl/binding/QuerydslPredicateBuilderUnitTests.java

@ -19,12 +19,10 @@ import static org.assertj.core.api.Assertions.*; @@ -19,12 +19,10 @@ import static org.assertj.core.api.Assertions.*;
import static org.assertj.core.api.Assumptions.*;
import static org.springframework.test.util.ReflectionTestUtils.*;
import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.data.querydsl.Address;
import org.springframework.data.querydsl.QSpecialUser;
import org.springframework.data.querydsl.QUser;
@ -189,9 +187,7 @@ class QuerydslPredicateBuilderUnitTests { @@ -189,9 +187,7 @@ class QuerydslPredicateBuilderUnitTests {
var predicate = builder.getPredicate(USER_TYPE, values, DEFAULT_BINDINGS);
var constant = (Constant<Object>) ((List<?>) getField(getField(predicate, "mixin"), "args")).get(0);
assertThat(constant.getConstant()).isEqualTo(Arrays.asList("Walt", "Heisenberg"));
assertThat(predicate).hasToString("Walt in user.nickNames && Heisenberg in user.nickNames");
}
@Test // GH-2649
@ -200,9 +196,8 @@ class QuerydslPredicateBuilderUnitTests { @@ -200,9 +196,8 @@ class QuerydslPredicateBuilderUnitTests {
values.add("user.nickNames", "Walt,Heisenberg");
var predicate = builder.getPredicate(TypeInformation.of(UserWrapper.class), values, DEFAULT_BINDINGS);
var constant = (Constant<Object>) ((List<?>) getField(getField(predicate, "mixin"), "args")).get(0);
assertThat(constant.getConstant()).isEqualTo(Arrays.asList("Walt", "Heisenberg"));
assertThat(predicate).hasToString("Walt in userWrapper.user.nickNames && Heisenberg in userWrapper.user.nickNames");
}
@Test // DATACMNS-883

Loading…
Cancel
Save