@@ -62,7 +62,7 @@ public void before() {
6262 @ Test
6363 @ Order (java .lang .Integer .MAX_VALUE )
6464 void cleanup () {
65- operations .indexOps (IndexCoordinates .of (indexNameProvider .getPrefix () + "*" )).delete ();
65+ operations .indexOps (IndexCoordinates .of (indexNameProvider .getPrefix () + '*' )).delete ();
6666 }
6767
6868 @ Test // #1143
@@ -85,11 +85,11 @@ void shouldReadPagesWithSearchAfter() {
8585 query .setSearchAfter (searchAfter );
8686 SearchHits <Entity > searchHits = operations .search (query , Entity .class );
8787
88- if (searchHits .getSearchHits ().size () == 0 ) {
88+ if (searchHits .getSearchHits ().isEmpty () ) {
8989 break ;
9090 }
91- foundEntities .addAll (searchHits .stream ().map (SearchHit ::getContent ).collect ( Collectors . toList () ));
92- searchAfter = searchHits .getSearchHit (( int ) ( searchHits .getSearchHits ().size () - 1 ) ).getSortValues ();
91+ foundEntities .addAll (searchHits .stream ().map (SearchHit ::getContent ).toList ());
92+ searchAfter = searchHits .getSearchHit (searchHits .getSearchHits ().size () - 1 ).getSortValues ();
9393
9494 if (++loop > 10 ) {
9595 fail ("loop not terminating" );
@@ -99,16 +99,69 @@ void shouldReadPagesWithSearchAfter() {
9999 assertThat (foundEntities ).containsExactlyElementsOf (entities );
100100 }
101101
102+ @ Test // #2678
103+ @ DisplayName ("should be able to handle different search after type values including null" )
104+ void shouldBeAbleToHandleDifferentSearchAfterTypeValuesIncludingNull () {
105+
106+ List <Entity > entities = IntStream .rangeClosed (1 , 10 )
107+ .mapToObj (i -> {
108+ var message = (i % 2 == 0 ) ? null : "message " + i ;
109+ var value = (i % 3 == 0 ) ? null : (long ) i ;
110+ return new Entity ((long ) i , message , value );
111+ })
112+ .collect (Collectors .toList ());
113+ operations .save (entities );
114+
115+ Query query = Query .findAll ();
116+ query .setPageable (PageRequest .of (0 , 3 ));
117+ query .addSort (Sort .by (Sort .Direction .ASC , "id" ));
118+ query .addSort (Sort .by (Sort .Direction .ASC , "keyword" ));
119+ query .addSort (Sort .by (Sort .Direction .ASC , "value" ));
120+
121+ List <Object > searchAfter = null ;
122+ List <Entity > foundEntities = new ArrayList <>();
123+
124+ int loop = 0 ;
125+ do {
126+ query .setSearchAfter (searchAfter );
127+ SearchHits <Entity > searchHits = operations .search (query , Entity .class );
128+
129+ if (searchHits .getSearchHits ().isEmpty ()) {
130+ break ;
131+ }
132+ foundEntities .addAll (searchHits .stream ().map (SearchHit ::getContent ).toList ());
133+ searchAfter = searchHits .getSearchHit (searchHits .getSearchHits ().size () - 1 ).getSortValues ();
134+
135+ if (++loop > 10 ) {
136+ fail ("loop not terminating" );
137+ }
138+ } while (true );
139+
140+ assertThat (foundEntities ).containsExactlyElementsOf (entities );
141+ }
142+
143+ @ SuppressWarnings ("unused" )
102144 @ Document (indexName = "#{@indexNameProvider.indexName()}" )
103145 private static class Entity {
104146 @ Nullable
105147 @ Id private Long id ;
106148 @ Nullable
107- @ Field (type = FieldType .Text ) private String message ;
149+ @ Field (type = FieldType .Keyword ) private String keyword ;
150+
151+ @ Nullable
152+ @ Field (type = FieldType .Long ) private Long value ;
153+
154+ public Entity () {}
108155
109- public Entity (@ Nullable Long id , @ Nullable String message ) {
156+ public Entity (@ Nullable Long id , @ Nullable String keyword ) {
110157 this .id = id ;
111- this .message = message ;
158+ this .keyword = keyword ;
159+ }
160+
161+ public Entity (@ Nullable Long id , @ Nullable String keyword , @ Nullable Long value ) {
162+ this .id = id ;
163+ this .keyword = keyword ;
164+ this .value = value ;
112165 }
113166
114167 @ Nullable
@@ -121,30 +174,44 @@ public void setId(@Nullable Long id) {
121174 }
122175
123176 @ Nullable
124- public String getMessage () {
125- return message ;
177+ public String getKeyword () {
178+ return keyword ;
179+ }
180+
181+ public void setKeyword (@ Nullable String keyword ) {
182+ this .keyword = keyword ;
183+ }
184+
185+ @ Nullable
186+ public Long getValue () {
187+ return value ;
126188 }
127189
128- public void setMessage (@ Nullable String message ) {
129- this .message = message ;
190+ public void setValue (@ Nullable Long value ) {
191+ this .value = value ;
130192 }
131193
132194 @ Override
133195 public boolean equals (Object o ) {
134196 if (this == o )
135197 return true ;
136- if (!( o instanceof Entity entity ))
198+ if (o == null || getClass () != o . getClass ( ))
137199 return false ;
138200
201+ Entity entity = (Entity ) o ;
202+
139203 if (!Objects .equals (id , entity .id ))
140204 return false ;
141- return Objects .equals (message , entity .message );
205+ if (!Objects .equals (keyword , entity .keyword ))
206+ return false ;
207+ return Objects .equals (value , entity .value );
142208 }
143209
144210 @ Override
145211 public int hashCode () {
146212 int result = id != null ? id .hashCode () : 0 ;
147- result = 31 * result + (message != null ? message .hashCode () : 0 );
213+ result = 31 * result + (keyword != null ? keyword .hashCode () : 0 );
214+ result = 31 * result + (value != null ? value .hashCode () : 0 );
148215 return result ;
149216 }
150217 }
0 commit comments