1515 */
1616package org .springframework .data .jdbc .repository .query ;
1717
18- import java .util .*;
19- import java .util .function .Predicate ;
20- import java .util .stream .Collectors ;
21-
2218import org .jspecify .annotations .Nullable ;
23-
2419import org .springframework .data .domain .*;
2520import org .springframework .data .jdbc .core .convert .JdbcConverter ;
2621import org .springframework .data .jdbc .core .convert .QueryMapper ;
3025import org .springframework .data .relational .core .mapping .AggregatePath ;
3126import org .springframework .data .relational .core .mapping .RelationalPersistentEntity ;
3227import org .springframework .data .relational .core .query .Criteria ;
33- import org .springframework .data .relational .core .sql .Column ;
34- import org .springframework .data .relational .core .sql .Expressions ;
35- import org .springframework .data .relational .core .sql .Functions ;
36- import org .springframework .data .relational .core .sql .LockMode ;
37- import org .springframework .data .relational .core .sql .Select ;
38- import org .springframework .data .relational .core .sql .SelectBuilder ;
39- import org .springframework .data .relational .core .sql .Table ;
28+ import org .springframework .data .relational .core .sql .*;
4029import org .springframework .data .relational .core .sql .render .SqlRenderer ;
4130import org .springframework .data .repository .query .ParametersSource ;
4231import org .springframework .data .util .Predicates ;
4332import org .springframework .jdbc .core .namedparam .MapSqlParameterSource ;
4433import org .springframework .jdbc .core .namedparam .SqlParameterSource ;
4534import org .springframework .lang .Contract ;
4635
36+ import java .util .*;
37+ import java .util .function .Predicate ;
38+ import java .util .stream .Collectors ;
39+
4740/**
4841 * Utility to render SQL statements for entities, count/exists projections, and slice queries. This is an internal
4942 * utility and should not be used outside of the framework as it can change without deprecation notice.
@@ -210,6 +203,8 @@ public String build(MapSqlParameterSource parameterSource) {
210203
211204 SelectBuilder .SelectOrdered selectOrderBuilder = applyCriteria (criteria , entity , table , parameterSource ,
212205 whereBuilder );
206+
207+ sort = applyCriteriaOrderBy (sort , scrollPosition );
213208 selectOrderBuilder = applyOrderBy (sort , entity , table , selectOrderBuilder );
214209
215210 SelectBuilder .BuildSelect completedBuildSelect = selectOrderBuilder ;
@@ -222,12 +217,30 @@ public String build(MapSqlParameterSource parameterSource) {
222217 return SqlRenderer .create (renderContextFactory .createRenderContext ()).render (select );
223218 }
224219
225- @ Nullable Criteria applyScrollCriteria (@ Nullable Criteria criteria , @ Nullable ScrollPosition position , Sort sort ) {
220+ Sort applyCriteriaOrderBy (Sort sort , @ Nullable ScrollPosition scrollPosition ) {
221+ if (!(scrollPosition instanceof KeysetScrollPosition ) || scrollPosition .isInitial ())
222+ return sort ;
223+
224+ Set <String > orders = sort .get ().map (Sort .Order ::getProperty ).collect (Collectors .toSet ());
225+
226+ Set <String > keys = ((KeysetScrollPosition ) scrollPosition ).getKeys ().keySet ();
227+
228+ Set <String > notSorted = keys .stream ().filter (it -> !orders .contains (it )).collect (Collectors .toSet ());
229+
230+ if (notSorted .isEmpty ())
231+ return sort ;
232+
233+ Sort .Direction defaultSort = sort .get ().map (Sort .Order ::getDirection ).findAny ()
234+ .orElse (Sort .DEFAULT_DIRECTION );
235+
236+ return sort
237+ .and (Sort .by (defaultSort , notSorted .toArray (new String [0 ])));
238+ }
239+
240+ Criteria applyScrollCriteria (Criteria criteria , @ Nullable ScrollPosition position , Sort sort ) {
226241 if (!(position instanceof KeysetScrollPosition ) || position .isInitial () || ((KeysetScrollPosition ) position ).getKeys ().isEmpty ())
227242 return criteria ;
228243
229- criteria = criteria == null ? Criteria .empty () : criteria ;
230-
231244 Map <String , Object > keys = ((KeysetScrollPosition ) position ).getKeys ();
232245 List <String > columns = new ArrayList <>(keys .keySet ());
233246 List <Object > values = new ArrayList <>(keys .values ());
0 commit comments