Browse Source

Convert only contents of collections using `StringBasedJdbcQuery`.

Contents of Iterables that aren't collections will not be converted individually.

Closes #1343
Original pull request: #1356
pull/1486/head
Jens Schauder 3 years ago committed by Mark Paluch
parent
commit
1226ca9be6
No known key found for this signature in database
GPG Key ID: 4406B84C1661DCD1
  1. 3
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java
  2. 44
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQueryUnitTests.java

3
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.lang.reflect.Constructor;
import java.sql.SQLType; import java.sql.SQLType;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
@ -188,7 +189,7 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery {
Assert.notNull(type, "@Query parameter type could not be resolved"); Assert.notNull(type, "@Query parameter type could not be resolved");
JdbcValue jdbcValue; JdbcValue jdbcValue;
if (value instanceof Iterable) { if (value instanceof Collection && resolvableType.hasGenerics()) {
List<Object> mapped = new ArrayList<>(); List<Object> mapped = new ArrayList<>();
SQLType jdbcType = null; SQLType jdbcType = null;

44
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.JDBCType;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.assertj.core.api.Assertions; import org.assertj.core.api.Assertions;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
@ -211,7 +213,6 @@ class StringBasedJdbcQueryUnitTests {
assertThat(sqlParameterSource.getValue("directions")).asList().containsExactlyInAnyOrder(-1, 1); assertThat(sqlParameterSource.getValue("directions")).asList().containsExactlyInAnyOrder(-1, 1);
} }
@Test // GH-1212 @Test // GH-1212
void doesNotConvertNonCollectionParameter() { void doesNotConvertNonCollectionParameter() {
@ -222,6 +223,18 @@ class StringBasedJdbcQueryUnitTests {
assertThat(sqlParameterSource.getValue("value")).isEqualTo(1); 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) { QueryFixture forMethod(String name, Class... paramTypes) {
return new QueryFixture(createMethod(name, paramTypes)); return new QueryFixture(createMethod(name, paramTypes));
} }
@ -321,6 +334,9 @@ class StringBasedJdbcQueryUnitTests {
@Query(value = "some sql statement") @Query(value = "some sql statement")
List<Object> findBySimpleValue(Integer value); List<Object> findBySimpleValue(Integer value);
@Query(value = "some sql statement")
List<Object> findByListContainer(ListContainer value);
@Query("SELECT * FROM table WHERE c = :#{myext.testValue} AND c2 = :#{myext.doSomething()}") @Query("SELECT * FROM table WHERE c = :#{myext.testValue} AND c2 = :#{myext.doSomething()}")
Object findBySpelExpression(Object object); Object findBySpelExpression(Object object);
} }
@ -417,6 +433,32 @@ class StringBasedJdbcQueryUnitTests {
} }
} }
static class ListContainer implements Iterable<String> {
private final List<String> values;
ListContainer(String... values) {
this.values = List.of(values);
}
@NotNull
@Override
public Iterator<String> iterator() {
return values.iterator();
}
}
@WritingConverter
enum ListContainerToStringConverter implements Converter<ListContainer, String> {
INSTANCE;
@Override
public String convert(ListContainer source) {
return source.values.get(0);
}
}
private static class DummyEntity { private static class DummyEntity {
private Long id; private Long id;

Loading…
Cancel
Save