From 0319f78e45ab1c0e7a686a5f9700510ad7c6112c Mon Sep 17 00:00:00 2001 From: banseok1216 Date: Sat, 6 Dec 2025 00:06:44 +0900 Subject: [PATCH] Fix restart position handling in AbstractPaginatedDataItemReader#jumpToItem Signed-off-by: banseok1216 --- .../data/AbstractPaginatedDataItemReader.java | 3 +- .../AbstractPaginatedDataItemReaderTests.java | 72 +++++++++++++++++ .../AbstractPagingItemReaderTests.java | 77 +++++++++++++++++++ 3 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 spring-batch-infrastructure/src/test/java/org/springframework/batch/infrastructure/item/data/AbstractPaginatedDataItemReaderTests.java create mode 100644 spring-batch-infrastructure/src/test/java/org/springframework/batch/infrastructure/item/database/AbstractPagingItemReaderTests.java diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/data/AbstractPaginatedDataItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/data/AbstractPaginatedDataItemReader.java index 8dcd5e749a..fff83d1df2 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/data/AbstractPaginatedDataItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/data/AbstractPaginatedDataItemReader.java @@ -118,9 +118,10 @@ protected void jumpToItem(int itemLastIndex) throws Exception { Iterator initialPage = doPageRead(); - for (; current >= 0; current--) { + for (; current > 0; current--) { initialPage.next(); } + this.results = initialPage; } finally { this.lock.unlock(); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/infrastructure/item/data/AbstractPaginatedDataItemReaderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/infrastructure/item/data/AbstractPaginatedDataItemReaderTests.java new file mode 100644 index 0000000000..87581f97ed --- /dev/null +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/infrastructure/item/data/AbstractPaginatedDataItemReaderTests.java @@ -0,0 +1,72 @@ +package org.springframework.batch.infrastructure.item.data; + +import org.junit.jupiter.api.Test; +import org.springframework.batch.infrastructure.item.ExecutionContext; + +import java.util.Iterator; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +class AbstractPaginatedDataItemReaderTests { + + static class PaginatedDataItemReader extends AbstractPaginatedDataItemReader { + + private final List data = List.of( + 0,1,2,3,4,5,6,7,8,9, + 10,11,12,13,14,15,16,17,18,19 + ); + + @Override + protected Iterator doPageRead() { + int start = page * pageSize; + int end = Math.min(start + pageSize, data.size()); + return data.subList(start, end).iterator(); + } + } + + @Test + void jumpToItem_shouldReadExactItem_afterJump() throws Exception { + PaginatedDataItemReader reader = new PaginatedDataItemReader(); + reader.open(new ExecutionContext()); + + reader.jumpToItem(7); + + Integer value = reader.read(); + assertEquals(7, value); + } + + @Test + void jumpToItem_zeroIndex() throws Exception { + PaginatedDataItemReader reader = new PaginatedDataItemReader(); + reader.open(new ExecutionContext()); + + reader.jumpToItem(0); + + Integer value = reader.read(); + assertEquals(0, value); + } + + @Test + void jumpToItem_lastItemInPage() throws Exception { + PaginatedDataItemReader reader = new PaginatedDataItemReader(); + reader.open(new ExecutionContext()); + + reader.jumpToItem(9); + + Integer value = reader.read(); + assertEquals(9, value); + } + + @Test + void jumpToItem_firstItemOfNextPage() throws Exception { + PaginatedDataItemReader reader = new PaginatedDataItemReader(); + reader.open(new ExecutionContext()); + + reader.jumpToItem(10); + + Integer value = reader.read(); + assertEquals(10, value); + } + +} \ No newline at end of file diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/infrastructure/item/database/AbstractPagingItemReaderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/infrastructure/item/database/AbstractPagingItemReaderTests.java new file mode 100644 index 0000000000..dd04194355 --- /dev/null +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/infrastructure/item/database/AbstractPagingItemReaderTests.java @@ -0,0 +1,77 @@ +package org.springframework.batch.infrastructure.item.database; + +import org.junit.jupiter.api.Test; +import org.springframework.batch.infrastructure.item.ExecutionContext; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +class AbstractPagingItemReaderTests { + + static class PagingItemReader extends AbstractPagingItemReader { + + private final List data = List.of( + 0,1,2,3,4,5,6,7,8,9, + 10,11,12,13,14,15,16,17,18,19 + ); + + @Override + protected void doReadPage() { + int start = getPage() * getPageSize(); + int end = Math.min(start + getPageSize(), data.size()); + + if (start >= data.size()) { + results = List.of(); + return; + } + + List pageData = new ArrayList<>(); + for (int i = start; i < end; i++) { + pageData.add(data.get(i)); + } + + this.results = pageData; + } + + @Override + protected void doOpen() {} + } + + @Test + void jumpToItem_shouldReadExactItem_afterJump() throws Exception { + PagingItemReader reader = new PagingItemReader(); + reader.open(new ExecutionContext()); + + reader.jumpToItem(7); + assertEquals(7, reader.read()); + } + + @Test + void jumpToItem_zeroIndex() throws Exception { + PagingItemReader reader = new PagingItemReader(); + reader.open(new ExecutionContext()); + + reader.jumpToItem(0); + assertEquals(0, reader.read()); + } + + @Test + void jumpToItem_lastItemInFirstPage() throws Exception { + PagingItemReader reader = new PagingItemReader(); + reader.open(new ExecutionContext()); + + reader.jumpToItem(9); + assertEquals(9, reader.read()); + } + + @Test + void jumpToItem_firstItemOfNextPage() throws Exception { + PagingItemReader reader = new PagingItemReader(); + reader.open(new ExecutionContext()); + + reader.jumpToItem(10); + assertEquals(10, reader.read()); + } +} \ No newline at end of file