Skip to content

Commit 3df1f34

Browse files
committed
Fix default skip limit when configuring fault tolerant steps
Resolves #5069
1 parent 24a464f commit 3df1f34

File tree

3 files changed

+28
-4
lines changed

3 files changed

+28
-4
lines changed

spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/ChunkOrientedStepBuilder.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import org.springframework.batch.core.step.item.ChunkOrientedStep;
5151
import org.springframework.batch.core.step.skip.AlwaysSkipItemSkipPolicy;
5252
import org.springframework.batch.core.step.skip.LimitCheckingExceptionHierarchySkipPolicy;
53+
import org.springframework.batch.core.step.skip.SkipLimitExceededException;
5354
import org.springframework.batch.core.step.skip.SkipPolicy;
5455
import org.springframework.batch.infrastructure.item.ItemProcessor;
5556
import org.springframework.batch.infrastructure.item.ItemReader;
@@ -108,7 +109,7 @@ public class ChunkOrientedStepBuilder<I, O> extends StepBuilderHelper<ChunkOrien
108109

109110
private final Set<Class<? extends Throwable>> skippableExceptions = new HashSet<>();
110111

111-
private long skipLimit = -1;
112+
private long skipLimit = 10;
112113

113114
private @Nullable AsyncTaskExecutor asyncTaskExecutor;
114115

@@ -347,6 +348,14 @@ public final ChunkOrientedStepBuilder<I, O> skip(Class<? extends Throwable>... s
347348
return self();
348349
}
349350

351+
/**
352+
* Set the skip limit for the step. This limit determines the maximum number of items
353+
* that can be skipped before the step fails. If the number of skipped items exceeds
354+
* this limit, the step will throw a {@link SkipLimitExceededException} and fail.
355+
* Defaults to 10.
356+
* @param skipLimit the skip limit to set
357+
* @return this for fluent chaining
358+
*/
350359
public ChunkOrientedStepBuilder<I, O> skipLimit(long skipLimit) {
351360
Assert.isTrue(skipLimit > 0, "skipLimit must be positive");
352361
this.skipLimit = skipLimit;

spring-batch-core/src/main/java/org/springframework/batch/core/step/skip/LimitCheckingExceptionHierarchySkipPolicy.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public class LimitCheckingExceptionHierarchySkipPolicy implements SkipPolicy {
3232

3333
private Set<Class<? extends Throwable>> skippableExceptions = new HashSet<>();
3434

35-
private long skipLimit = -1;
35+
private final long skipLimit;
3636

3737
/**
3838
* Create a new {@link LimitCheckingExceptionHierarchySkipPolicy} instance.
@@ -41,7 +41,7 @@ public class LimitCheckingExceptionHierarchySkipPolicy implements SkipPolicy {
4141
*/
4242
public LimitCheckingExceptionHierarchySkipPolicy(Set<Class<? extends Throwable>> skippableExceptions,
4343
long skipLimit) {
44-
Assert.notEmpty(skippableExceptions, "The skippableExceptions must not be empty");
44+
Assert.notNull(skippableExceptions, "The skippableExceptions must not be null");
4545
Assert.isTrue(skipLimit > 0, "The skipLimit must be greater than zero");
4646
this.skippableExceptions = skippableExceptions;
4747
this.skipLimit = skipLimit;

spring-batch-core/src/test/java/org/springframework/batch/core/step/item/ChunkOrientedStepIntegrationTests.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616
package org.springframework.batch.core.step.item;
1717

18-
import java.util.Map;
18+
import java.util.List;
1919
import java.util.Set;
2020

2121
import javax.sql.DataSource;
@@ -38,6 +38,7 @@
3838
import org.springframework.batch.core.launch.JobOperator;
3939
import org.springframework.batch.core.repository.JobRepository;
4040
import org.springframework.batch.core.step.builder.ChunkOrientedStepBuilder;
41+
import org.springframework.batch.core.step.builder.StepBuilder;
4142
import org.springframework.batch.core.step.skip.LimitCheckingExceptionHierarchySkipPolicy;
4243
import org.springframework.batch.core.step.skip.SkipLimitExceededException;
4344
import org.springframework.batch.infrastructure.item.ItemProcessor;
@@ -48,6 +49,7 @@
4849
import org.springframework.batch.infrastructure.item.file.FlatFileItemReader;
4950
import org.springframework.batch.infrastructure.item.file.FlatFileParseException;
5051
import org.springframework.batch.infrastructure.item.file.builder.FlatFileItemReaderBuilder;
52+
import org.springframework.batch.infrastructure.item.support.ListItemReader;
5153
import org.springframework.beans.factory.annotation.Value;
5254
import org.springframework.context.ApplicationContext;
5355
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@@ -63,6 +65,8 @@
6365
import org.springframework.jdbc.support.JdbcTransactionManager;
6466
import org.springframework.test.jdbc.JdbcTestUtils;
6567

68+
import static org.mockito.Mockito.mock;
69+
6670
/**
6771
* Integration tests for {@link ChunkOrientedStep}.
6872
*
@@ -73,6 +77,17 @@ public class ChunkOrientedStepIntegrationTests {
7377
// TODO use parameterized tests for serial and concurrent steps
7478
// The outcome should be the same for both
7579

80+
@Test
81+
void testFaultTolerantChunkOrientedStepSetupWithDefaultSkipLimit() {
82+
Assertions.assertDoesNotThrow(() -> new StepBuilder(mock()).chunk(5)
83+
.reader(new ListItemReader<>(List.of("item1", "item2")))
84+
.writer(items -> {
85+
})
86+
.faultTolerant()
87+
.skip(Exception.class)
88+
.build());
89+
}
90+
7691
@Test
7792
void testChunkOrientedStep() throws Exception {
7893
// given

0 commit comments

Comments
 (0)