@@ -249,39 +249,42 @@ Criteria applyScrollCriteria(Criteria criteria, @Nullable ScrollPosition positio
249249 List <String > columns = new ArrayList <>(keys .keySet ());
250250 List <Object > values = new ArrayList <>(keys .values ());
251251
252+ if (columns .isEmpty () || values .isEmpty ())
253+ return criteria ;
254+
252255 Map <String , Sort .Direction > directions =
253256 sort .stream ().collect (Collectors .toMap (Sort .Order ::getProperty , Sort .Order ::getDirection ));
254257
255- String primary = columns .get (0 );
256- Object primaryValue = values .get (0 );
258+ Sort .Direction dir = directions .getOrDefault (columns .get (0 ), Sort .DEFAULT_DIRECTION );
257259
258- Criteria primaryCompare ;
259- Sort .Direction dir = directions .getOrDefault (primary , Sort .DEFAULT_DIRECTION );
260+ Criteria scroll = buildKeysetCriteria (columns , values , keyset .scrollsForward (), dir );
260261
261- if (keyset .scrollsForward () ^ dir .isDescending ()) {
262- primaryCompare = columns .size () != 1 ? Criteria .where (primary ).greaterThanOrEquals (primaryValue ) : Criteria .where (primary ).greaterThan (primaryValue );
263- } else {
264- primaryCompare = columns .size () != 1 ? Criteria .where (primary ).lessThanOrEquals (primaryValue ) : Criteria .where (primary ).lessThan (primaryValue );
265- }
262+ return criteria .and (scroll );
263+ }
266264
267- if (columns .size () == 1 )
268- return criteria .and (primaryCompare );
265+ Criteria buildKeysetCriteria (List <String > columns , List <Object > values , boolean isForward , Sort .Direction dir ) {
266+ if (columns .isEmpty ())
267+ return Criteria .empty ();
269268
270- Criteria tupleCompare = null ;
271- for (int i = 0 ; i < columns .size (); i ++) {
272- Criteria orCriteria ;
273- String col = columns .get (i );
274- Object val = values .get (i );
269+ String column = columns .get (0 );
270+ Object value = values .get (0 );
275271
276- Sort .Direction colDir = directions .getOrDefault (col , dir );
277- boolean asc = keyset .scrollsForward () ? colDir .isAscending () : colDir .isDescending ();
272+ boolean isAscending = isForward ^ dir .isDescending ();
278273
279- orCriteria = asc ? Criteria .where (col ).greaterThan (val ) : Criteria .where (col ).lessThan (val );
274+ Criteria gte = isAscending
275+ ? Criteria .where (column ).greaterThanOrEquals (value )
276+ : Criteria .where (column ).lessThanOrEquals (value );
280277
281- tupleCompare = (tupleCompare == null ) ? orCriteria : tupleCompare .or (orCriteria );
282- }
278+ Criteria gt = isAscending
279+ ? Criteria .where (column ).greaterThan (value )
280+ : Criteria .where (column ).lessThan (value );
281+
282+ if (columns .size () == 1 )
283+ return gt ;
284+
285+ Criteria nested = buildKeysetCriteria (columns .subList (1 , columns .size ()), values .subList (1 , values .size ()), isForward , dir );
283286
284- return criteria .and (primaryCompare ). and ( tupleCompare );
287+ return gte .and (gt . or ( nested ) );
285288 }
286289
287290 SelectBuilder .SelectOrdered applyOrderBy (Sort sort , RelationalPersistentEntity <?> entity , Table table ,
0 commit comments