Skip to content

Commit d5fbb54

Browse files
banseok1216fmbenhassine
authored andcommitted
Fix restart position handling in AbstractPaginatedDataItemReader#jumpToItem
Resolves #5136 Signed-off-by: banseok1216 <[email protected]>
1 parent 868849e commit d5fbb54

File tree

3 files changed

+182
-2
lines changed

3 files changed

+182
-2
lines changed

spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/data/AbstractPaginatedDataItemReader.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013-2024 the original author or authors.
2+
* Copyright 2013-present the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -118,9 +118,10 @@ protected void jumpToItem(int itemLastIndex) throws Exception {
118118

119119
Iterator<T> initialPage = doPageRead();
120120

121-
for (; current >= 0; current--) {
121+
for (; current > 0; current--) {
122122
initialPage.next();
123123
}
124+
this.results = initialPage;
124125
}
125126
finally {
126127
this.lock.unlock();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
* Copyright 2026-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.batch.infrastructure.item.data;
17+
18+
import org.junit.jupiter.api.Test;
19+
import org.springframework.batch.infrastructure.item.ExecutionContext;
20+
21+
import java.util.Iterator;
22+
import java.util.List;
23+
24+
import static org.junit.jupiter.api.Assertions.assertEquals;
25+
26+
class AbstractPaginatedDataItemReaderTests {
27+
28+
static class PaginatedDataItemReader extends AbstractPaginatedDataItemReader<Integer> {
29+
30+
private final List<Integer> data = List.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
31+
19);
32+
33+
@Override
34+
protected Iterator<Integer> doPageRead() {
35+
int start = page * pageSize;
36+
int end = Math.min(start + pageSize, data.size());
37+
return data.subList(start, end).iterator();
38+
}
39+
40+
}
41+
42+
@Test
43+
void jumpToItem_shouldReadExactItem_afterJump() throws Exception {
44+
PaginatedDataItemReader reader = new PaginatedDataItemReader();
45+
reader.open(new ExecutionContext());
46+
47+
reader.jumpToItem(7);
48+
49+
Integer value = reader.read();
50+
assertEquals(7, value);
51+
}
52+
53+
@Test
54+
void jumpToItem_zeroIndex() throws Exception {
55+
PaginatedDataItemReader reader = new PaginatedDataItemReader();
56+
reader.open(new ExecutionContext());
57+
58+
reader.jumpToItem(0);
59+
60+
Integer value = reader.read();
61+
assertEquals(0, value);
62+
}
63+
64+
@Test
65+
void jumpToItem_lastItemInPage() throws Exception {
66+
PaginatedDataItemReader reader = new PaginatedDataItemReader();
67+
reader.open(new ExecutionContext());
68+
69+
reader.jumpToItem(9);
70+
71+
Integer value = reader.read();
72+
assertEquals(9, value);
73+
}
74+
75+
@Test
76+
void jumpToItem_firstItemOfNextPage() throws Exception {
77+
PaginatedDataItemReader reader = new PaginatedDataItemReader();
78+
reader.open(new ExecutionContext());
79+
80+
reader.jumpToItem(10);
81+
82+
Integer value = reader.read();
83+
assertEquals(10, value);
84+
}
85+
86+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
* Copyright 2026-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.batch.infrastructure.item.database;
17+
18+
import org.junit.jupiter.api.Test;
19+
import org.springframework.batch.infrastructure.item.ExecutionContext;
20+
21+
import java.util.ArrayList;
22+
import java.util.List;
23+
24+
import static org.junit.jupiter.api.Assertions.assertEquals;
25+
26+
class AbstractPagingItemReaderTests {
27+
28+
static class PagingItemReader extends AbstractPagingItemReader<Integer> {
29+
30+
private final List<Integer> data = List.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
31+
19);
32+
33+
@Override
34+
protected void doReadPage() {
35+
int start = getPage() * getPageSize();
36+
int end = Math.min(start + getPageSize(), data.size());
37+
38+
if (start >= data.size()) {
39+
results = List.of();
40+
return;
41+
}
42+
43+
List<Integer> pageData = new ArrayList<>();
44+
for (int i = start; i < end; i++) {
45+
pageData.add(data.get(i));
46+
}
47+
48+
this.results = pageData;
49+
}
50+
51+
@Override
52+
protected void doOpen() {
53+
}
54+
55+
}
56+
57+
@Test
58+
void jumpToItem_shouldReadExactItem_afterJump() throws Exception {
59+
PagingItemReader reader = new PagingItemReader();
60+
reader.open(new ExecutionContext());
61+
62+
reader.jumpToItem(7);
63+
assertEquals(7, reader.read());
64+
}
65+
66+
@Test
67+
void jumpToItem_zeroIndex() throws Exception {
68+
PagingItemReader reader = new PagingItemReader();
69+
reader.open(new ExecutionContext());
70+
71+
reader.jumpToItem(0);
72+
assertEquals(0, reader.read());
73+
}
74+
75+
@Test
76+
void jumpToItem_lastItemInFirstPage() throws Exception {
77+
PagingItemReader reader = new PagingItemReader();
78+
reader.open(new ExecutionContext());
79+
80+
reader.jumpToItem(9);
81+
assertEquals(9, reader.read());
82+
}
83+
84+
@Test
85+
void jumpToItem_firstItemOfNextPage() throws Exception {
86+
PagingItemReader reader = new PagingItemReader();
87+
reader.open(new ExecutionContext());
88+
89+
reader.jumpToItem(10);
90+
assertEquals(10, reader.read());
91+
}
92+
93+
}

0 commit comments

Comments
 (0)