Skip to content

Commit b24cb44

Browse files
committed
Fall back to collection if stream query has custom result set extractor
Specifying a custom result set extractor doesn't make sense when using streams because the result set extractor always considers the entire result. This loads the entire stream into memory anyways.
1 parent d2aae2f commit b24cb44

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

Diff for: spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/AbstractJdbcQuery.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ protected JdbcQueryExecution<?> getQueryExecution(JdbcQueryMethod queryMethod,
9595
}
9696

9797
if (queryMethod.isStreamQuery()) {
98-
return streamQuery(rowMapper);
98+
return extractor != null ? getQueryExecution(extractor) : streamQuery(rowMapper);
9999
}
100100

101101
return extractor != null ? getQueryExecution(extractor) : singleObjectQuery(rowMapper);

Diff for: spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQueryUnitTests.java

+16
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.assertj.core.api.Assertions;
2828
import org.junit.jupiter.api.BeforeEach;
2929
import org.junit.jupiter.api.Test;
30+
import org.mockito.ArgumentCaptor;
3031
import org.springframework.dao.DataAccessException;
3132
import org.springframework.data.domain.Page;
3233
import org.springframework.data.domain.Pageable;
@@ -140,6 +141,18 @@ public void streamQueryCallsQueryForStreamOnOperations() {
140141
verify(operations).queryForStream(eq("some sql statement"), any(SqlParameterSource.class), any(RowMapper.class));
141142
}
142143

144+
@Test // DATAJDBC-356
145+
void streamQueryFallsBackToCollectionQueryWhenCustomResultSetExtractorIsSpecified() {
146+
JdbcQueryMethod queryMethod = createMethod("findAllWithStreamReturnTypeAndResultSetExtractor");
147+
StringBasedJdbcQuery query = createQuery(queryMethod);
148+
149+
query.execute(new Object[] {});
150+
151+
ArgumentCaptor<ResultSetExtractor> captor = ArgumentCaptor.forClass(ResultSetExtractor.class);
152+
verify(operations).query(eq("some sql statement"), any(SqlParameterSource.class), captor.capture());
153+
assertThat(captor.getValue()).isInstanceOf(CustomResultSetExtractor.class);
154+
}
155+
143156
@Test // GH-774
144157
public void sliceQueryNotSupported() {
145158

@@ -189,6 +202,9 @@ interface MyRepository extends Repository<Object, Long> {
189202
@Query(value = "some sql statement")
190203
Stream<Object> findAllWithStreamReturnType();
191204

205+
@Query(value = "some sql statement", resultSetExtractorClass = CustomResultSetExtractor.class)
206+
Stream<Object> findAllWithStreamReturnTypeAndResultSetExtractor();
207+
192208
List<Object> noAnnotation();
193209

194210
@Query(value = "some sql statement")

0 commit comments

Comments
 (0)