Skip to content

Commit

Permalink
Unwrap nested collections in default Querydsl binding.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
mp911de committed Jun 2, 2023
1 parent 2b7fed5 commit 085c322
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,16 @@ public Optional<Predicate> bind(Path<?> path, Collection<? extends Object> value
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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@

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 {

Expand Down Expand Up @@ -64,6 +66,14 @@ void shouldCreatePredicateWithContainingWhenPropertyIsCollectionLikeAndValueIsOb
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() {

Expand All @@ -73,7 +83,7 @@ void shouldCreatePredicateWithInWhenPropertyIsAnObjectAndValueIsACollection() {
}

@Test
void testname() {
void shouldNotBindEmptyParameterCollection() {
assertThat(binding.bind(QUser.user.lastname, Collections.emptySet())).isNotPresent();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,10 @@
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;
Expand Down Expand Up @@ -189,9 +187,7 @@ void resolvesCommaSeparatedArgumentToListCorrectly() {

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
Expand All @@ -200,9 +196,8 @@ void resolvesCommaSeparatedArgumentToListCorrectlyForNestedPath() {
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
Expand Down

0 comments on commit 085c322

Please sign in to comment.