diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/QueryMapper.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/QueryMapper.java index 817ad88e98..3ab54cc5f4 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/QueryMapper.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/QueryMapper.java @@ -440,7 +440,7 @@ private Condition mapEmbeddedObjectCondition(CriteriaDefinition criteria, MapSql @Nullable private Object convertValue(Comparator comparator, @Nullable Object value, TypeInformation typeHint) { - if (Comparator.IN.equals(comparator) && value instanceof Collection collection && !collection.isEmpty()) { + if ((Comparator.IN.equals(comparator) || Comparator.NOT_IN.equals(comparator)) && value instanceof Collection collection && !collection.isEmpty()) { Collection mapped = new ArrayList<>(collection.size()); diff --git a/spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/query/QueryMapper.java b/spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/query/QueryMapper.java index 5174799a79..ffc3dbb499 100644 --- a/spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/query/QueryMapper.java +++ b/spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/query/QueryMapper.java @@ -411,7 +411,7 @@ public Parameter getBindValue(Parameter value) { @Nullable private Object convertValue(Comparator comparator, @Nullable Object value, TypeInformation typeHint) { - if (Comparator.IN.equals(comparator) && value instanceof Collection collection && !collection.isEmpty()) { + if ((Comparator.IN.equals(comparator) || Comparator.NOT_IN.equals(comparator)) && value instanceof Collection collection && !collection.isEmpty()) { Collection mapped = new ArrayList<>(collection.size()); diff --git a/spring-data-r2dbc/src/test/java/org/springframework/data/r2dbc/query/QueryMapperUnitTests.java b/spring-data-r2dbc/src/test/java/org/springframework/data/r2dbc/query/QueryMapperUnitTests.java index 26f203c809..c9ac48e043 100644 --- a/spring-data-r2dbc/src/test/java/org/springframework/data/r2dbc/query/QueryMapperUnitTests.java +++ b/spring-data-r2dbc/src/test/java/org/springframework/data/r2dbc/query/QueryMapperUnitTests.java @@ -19,9 +19,7 @@ import static org.mockito.Mockito.*; import static org.springframework.data.domain.Sort.Order.*; -import java.util.Collections; -import java.util.List; -import java.util.Objects; +import java.util.*; import org.junit.jupiter.api.Test; import org.springframework.core.convert.converter.Converter; @@ -59,9 +57,11 @@ class QueryMapperUnitTests { private QueryMapper mapper = createMapper(PostgresDialect.INSTANCE); QueryMapper createMapper(R2dbcDialect dialect) { + return createMapper(dialect, JsonNodeToStringConverter.INSTANCE, StringToJsonNodeConverter.INSTANCE); + } - R2dbcCustomConversions conversions = R2dbcCustomConversions.of(dialect, JsonNodeToStringConverter.INSTANCE, - StringToJsonNodeConverter.INSTANCE); + QueryMapper createMapper(R2dbcDialect dialect, Converter... converters) { + R2dbcCustomConversions conversions = R2dbcCustomConversions.of(dialect, Arrays.asList(converters)); R2dbcMappingContext context = new R2dbcMappingContext(); context.setSimpleTypeHolder(conversions.getSimpleTypeHolder()); @@ -358,6 +358,18 @@ void shouldMapIsNotIn() { assertThat(bindings.getCondition()).hasToString("person.name NOT IN (?[$1], ?[$2], ?[$3])"); } + @Test + void sholdMapIsNotInWithCollectionToStringConverter() { + + mapper = createMapper(PostgresDialect.INSTANCE, JsonNodeToStringConverter.INSTANCE, StringToJsonNodeConverter.INSTANCE, CollectionToStringConverter.INSTANCE); + + Criteria criteria = Criteria.where("name").notIn("a", "b", "c"); + + BoundCondition bindings = map(criteria); + + assertThat(bindings.getCondition()).hasToString("person.name NOT IN (?[$1], ?[$2], ?[$3])"); + } + @Test // gh-64 void shouldMapIsGt() { @@ -574,6 +586,15 @@ public String convert(JsonNode source) { } } + enum CollectionToStringConverter implements Converter, String> { + INSTANCE; + @Override + public String convert(Collection source) { + return source.toString(); + } + } + + enum StringToJsonNodeConverter implements Converter { INSTANCE;