diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java index 87d18b577..fa83340fe 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java @@ -20,6 +20,7 @@ import static org.springframework.data.jdbc.repository.query.JdbcQueryExecution. import java.lang.reflect.Constructor; import java.sql.SQLType; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import org.springframework.beans.BeanUtils; @@ -188,7 +189,7 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery { Assert.notNull(type, "@Query parameter type could not be resolved"); JdbcValue jdbcValue; - if (value instanceof Iterable) { + if (value instanceof Collection && resolvableType.hasGenerics()) { List mapped = new ArrayList<>(); SQLType jdbcType = null; diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQueryUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQueryUnitTests.java index 5d6568500..bdce29116 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQueryUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQueryUnitTests.java @@ -22,12 +22,14 @@ import java.lang.reflect.Method; import java.sql.JDBCType; import java.sql.ResultSet; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import java.util.Properties; import java.util.Set; import java.util.stream.Stream; import org.assertj.core.api.Assertions; +import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; @@ -211,7 +213,6 @@ class StringBasedJdbcQueryUnitTests { assertThat(sqlParameterSource.getValue("directions")).asList().containsExactlyInAnyOrder(-1, 1); } - @Test // GH-1212 void doesNotConvertNonCollectionParameter() { @@ -222,6 +223,18 @@ class StringBasedJdbcQueryUnitTests { assertThat(sqlParameterSource.getValue("value")).isEqualTo(1); } + @Test // GH-1343 + void appliesConverterToIterable() { + + SqlParameterSource sqlParameterSource = forMethod("findByListContainer", ListContainer.class) // + .withCustomConverters(ListContainerToStringConverter.INSTANCE) + .withArguments(new ListContainer("one", "two", "three")) // + .extractParameterSource(); + + assertThat(sqlParameterSource.getValue("value")).isEqualTo("one"); + + } + QueryFixture forMethod(String name, Class... paramTypes) { return new QueryFixture(createMethod(name, paramTypes)); } @@ -321,6 +334,9 @@ class StringBasedJdbcQueryUnitTests { @Query(value = "some sql statement") List findBySimpleValue(Integer value); + @Query(value = "some sql statement") + List findByListContainer(ListContainer value); + @Query("SELECT * FROM table WHERE c = :#{myext.testValue} AND c2 = :#{myext.doSomething()}") Object findBySpelExpression(Object object); } @@ -417,6 +433,32 @@ class StringBasedJdbcQueryUnitTests { } } + static class ListContainer implements Iterable { + + private final List values; + + ListContainer(String... values) { + this.values = List.of(values); + } + + @NotNull + @Override + public Iterator iterator() { + return values.iterator(); + } + } + + @WritingConverter + enum ListContainerToStringConverter implements Converter { + + INSTANCE; + + @Override + public String convert(ListContainer source) { + return source.values.get(0); + } + } + private static class DummyEntity { private Long id;