Browse Source

Apply sorting to select and slice queries only.

StatementFactory now only applies ordering to select and slice queries without applying ordering to count and exists projections.

Closes #2190
issue/2199
Mark Paluch 1 week ago
parent
commit
ee9b4b94c3
No known key found for this signature in database
GPG Key ID: 55BC6374BAA9D973
  1. 5
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StatementFactory.java
  2. 56
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/StatementFactoryUnitTests.java

5
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StatementFactory.java

@ -201,7 +201,10 @@ public class StatementFactory {
SelectBuilder.SelectWhere whereBuilder = applyLimitAndOffset(limitOffsetBuilder); SelectBuilder.SelectWhere whereBuilder = applyLimitAndOffset(limitOffsetBuilder);
SelectBuilder.SelectOrdered selectOrderBuilder = applyCriteria(criteria, entity, table, parameterSource, SelectBuilder.SelectOrdered selectOrderBuilder = applyCriteria(criteria, entity, table, parameterSource,
whereBuilder); whereBuilder);
selectOrderBuilder = applyOrderBy(sort, entity, table, selectOrderBuilder);
if (mode == Mode.SLICE || mode == Mode.SELECT) {
selectOrderBuilder = applyOrderBy(sort, entity, table, selectOrderBuilder);
}
SelectBuilder.BuildSelect completedBuildSelect = selectOrderBuilder; SelectBuilder.BuildSelect completedBuildSelect = selectOrderBuilder;
if (this.lockMode != null) { if (this.lockMode != null) {

56
spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/StatementFactoryUnitTests.java

@ -23,6 +23,8 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Id;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jdbc.core.convert.JdbcCustomConversions; import org.springframework.data.jdbc.core.convert.JdbcCustomConversions;
import org.springframework.data.jdbc.core.convert.JdbcTypeFactory; import org.springframework.data.jdbc.core.convert.JdbcTypeFactory;
import org.springframework.data.jdbc.core.convert.MappingJdbcConverter; import org.springframework.data.jdbc.core.convert.MappingJdbcConverter;
@ -41,30 +43,76 @@ class StatementFactoryUnitTests {
JdbcMappingContext mappingContext = new JdbcMappingContext(); JdbcMappingContext mappingContext = new JdbcMappingContext();
MappingJdbcConverter converter; MappingJdbcConverter converter;
MapSqlParameterSource parameterSource = new MapSqlParameterSource();
StatementFactory statementFactory;
@BeforeEach @BeforeEach
void setUp() { void setUp() {
JdbcCustomConversions conversions = JdbcCustomConversions.of(JdbcH2Dialect.INSTANCE, List.of()); JdbcCustomConversions conversions = JdbcCustomConversions.of(JdbcH2Dialect.INSTANCE, List.of());
mappingContext.setSimpleTypeHolder(conversions.getSimpleTypeHolder()); mappingContext.setSimpleTypeHolder(conversions.getSimpleTypeHolder());
mappingContext.setForceQuote(false);
mappingContext.afterPropertiesSet(); mappingContext.afterPropertiesSet();
converter = new MappingJdbcConverter(mappingContext, (identifier, path) -> null, conversions, converter = new MappingJdbcConverter(mappingContext, (identifier, path) -> null, conversions,
JdbcTypeFactory.unsupported()); JdbcTypeFactory.unsupported());
statementFactory = new StatementFactory(converter, JdbcH2Dialect.INSTANCE);
} }
@Test // GH-2162 @Test // GH-2162
void statementFactoryConsidersQualifiedTableName() { void sliceConsiderSort() {
StatementFactory.SelectionBuilder selection = statementFactory.slice(User.class);
selection.page(PageRequest.of(0, 1, Sort.by("id")));
String sql = selection.build(parameterSource);
assertThat(sql).contains("SELECT user.ID").contains("ORDER BY user.ID");
}
@Test // GH-2162
void selectConsiderSort() {
StatementFactory.SelectionBuilder selection = statementFactory.select(User.class);
selection.page(PageRequest.of(0, 1, Sort.by("id")));
String sql = selection.build(parameterSource);
assertThat(sql).contains("SELECT user.ID").contains("ORDER BY user.ID");
}
@Test // GH-2162
void countDoesNotConsiderSort() {
MapSqlParameterSource parameterSource = new MapSqlParameterSource(); StatementFactory.SelectionBuilder selection = statementFactory.count(User.class);
selection.page(PageRequest.of(0, 1, Sort.by("id")));
String sql = selection.build(parameterSource);
assertThat(sql).isEqualTo("SELECT COUNT(*) FROM user");
}
@Test // GH-2162
void existsDoesNotConsiderSort() {
StatementFactory.SelectionBuilder selection = statementFactory.exists(User.class);
selection.page(PageRequest.of(0, 1, Sort.by("id")));
String sql = selection.build(parameterSource);
assertThat(sql).isEqualTo("SELECT user.ID FROM user OFFSET 0 ROWS FETCH FIRST 1 ROWS ONLY");
}
@Test // GH-2162
void statementFactoryConsidersQualifiedTableName() {
StatementFactory statementFactory = new StatementFactory(converter, JdbcH2Dialect.INSTANCE);
StatementFactory.SelectionBuilder selection = statementFactory.select(Media.class); StatementFactory.SelectionBuilder selection = statementFactory.select(Media.class);
String sql = selection.build(parameterSource); String sql = selection.build(parameterSource);
assertThat(sql).contains("SELECT \"archive\".\"media\".").contains("ROM \"archive\".\"media\""); assertThat(sql).contains("SELECT archive.media.").contains("ROM archive.media");
} }
@Table(schema = "archive", name = "media") @Table(schema = "archive", name = "media")
public record Media(@Id Long id, String objectType, Long objectId) { public record Media(@Id Long id, String objectType, Long objectId) {
} }
@Table(name = "user")
public record User(@Id Long id, String objectType, Long objectId) {
}
} }

Loading…
Cancel
Save