Skip to content

Commit 7e85b50

Browse files
committed
Merge conflict
2 parents 1061041 + 853c960 commit 7e85b50

File tree

41 files changed

+714
-535
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+714
-535
lines changed

archetypes/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<parent>
1010
<groupId>org.springframework.batch</groupId>
1111
<artifactId>spring-batch-parent</artifactId>
12-
<version>3.0.0.BUILD-SNAPSHOT</version>
12+
<version>2.2.2.BUILD-SNAPSHOT</version>
1313
<relativePath>../spring-batch-parent</relativePath>
1414
</parent>
1515
<modules>

archetypes/simple-cli/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<modelVersion>4.0.0</modelVersion>
44
<groupId>org.springframework.batch</groupId>
55
<artifactId>spring-batch-simple-cli</artifactId>
6-
<version>3.0.0.BUILD-SNAPSHOT</version>
6+
<version>2.2.2.BUILD-SNAPSHOT</version>
77
<packaging>jar</packaging>
88
<name>Commandline</name>
99
<url>http://www.springframework.org/spring-batch/archetypes/simple-cli-archetype</url>
@@ -15,7 +15,7 @@
1515
</description>
1616
<properties>
1717
<spring.framework.version>3.2.0.RELEASE</spring.framework.version>
18-
<spring.batch.version>3.0.0.BUILD-SNAPSHOT</spring.batch.version>
18+
<spring.batch.version>2.2.2.BUILD-SNAPSHOT</spring.batch.version>
1919
<dependency.locations.enabled>false</dependency.locations.enabled>
2020
<junit.version>4.10</junit.version>
2121
<compiler.target.version>1.6</compiler.target.version>

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<name>Spring Batch</name>
77
<description>Spring Batch provides tools for enterprise batch or bulk processing. It can be used to wire up jobs, and track
88
their execution, or simply as an optimization for repetitive processing in a transactional environment. Spring Batch is part of the Spring Portfolio.</description>
9-
<version>3.0.0.BUILD-SNAPSHOT</version>
9+
<version>2.2.2.BUILD-SNAPSHOT</version>
1010
<packaging>pom</packaging>
1111
<modules>
1212
<module>spring-batch-parent</module>

spring-batch-core-tests/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<parent>
99
<groupId>org.springframework.batch</groupId>
1010
<artifactId>spring-batch-parent</artifactId>
11-
<version>3.0.0.BUILD-SNAPSHOT</version>
11+
<version>2.2.2.BUILD-SNAPSHOT</version>
1212
<relativePath>../spring-batch-parent</relativePath>
1313
</parent>
1414
<profiles>

spring-batch-core/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<parent>
1010
<groupId>org.springframework.batch</groupId>
1111
<artifactId>spring-batch-parent</artifactId>
12-
<version>3.0.0.BUILD-SNAPSHOT</version>
12+
<version>2.2.2.BUILD-SNAPSHOT</version>
1313
<relativePath>../spring-batch-parent</relativePath>
1414
</parent>
1515
<dependencies>

spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/EnableBatchProcessing.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
* <pre class="code">
4040
* &#064;Configuration
4141
* &#064;EnableBatchProcessing
42-
* &#064;Import(DataSourceCnfiguration.class)
42+
* &#064;Import(DataSourceConfiguration.class)
4343
* public class AppConfig {
4444
*
4545
* &#064;Autowired
@@ -169,4 +169,4 @@
169169
*/
170170
boolean modular() default false;
171171

172-
}
172+
}

spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/StepScope.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
* }
2424
* </pre>
2525
*
26-
* <p>Marking a &#64;Bean as &#64;StepScope is equivalent to marking it as <code>&#64;Scope(value="step", proxyMode=INTERFACES)</code></p>
26+
* <p>Marking a &#64;Bean as &#64;StepScope is equivalent to marking it as <code>&#64;Scope(value="step", proxyMode=TARGET_CLASS)</code></p>
2727
*
2828
* @author Dave Syer
2929
*

spring-batch-core/src/main/java/org/springframework/batch/core/step/item/FaultTolerantChunkProcessor.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,9 @@ public O doWithRetry(RetryContext context) throws Exception {
223223
}
224224
else {
225225
output = doProcess(item);
226-
if (!processorTransactional && !data.scanning()) {
226+
if (output == null) {
227+
data.incrementFilterCount();
228+
} else if (!processorTransactional && !data.scanning()) {
227229
cache.add(output);
228230
}
229231
}
@@ -254,8 +256,7 @@ else if (shouldSkip(itemProcessSkipPolicy, e, contribution.getStepSkipCount()))
254256
}
255257
if (output == null) {
256258
// No need to re-process filtered items
257-
iterator.remove();
258-
data.incrementFilterCount();
259+
iterator.remove();
259260
}
260261
return output;
261262
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
-- create the requisite table
3+
4+
CREATE TABLE BATCH_JOB_EXECUTION_PARAMS (
5+
JOB_EXECUTION_ID BIGINT NOT NULL ,
6+
TYPE_CD VARCHAR(6) NOT NULL ,
7+
KEY_NAME VARCHAR(100) NOT NULL ,
8+
STRING_VAL VARCHAR(250) ,
9+
DATE_VAL TIMESTAMP DEFAULT NULL ,
10+
LONG_VAL BIGINT ,
11+
DOUBLE_VAL DOUBLE PRECISION ,
12+
IDENTIFYING CHAR(1) NOT NULL ,
13+
constraint JOB_EXEC_PARAMS_FK foreign key (JOB_EXECUTION_ID)
14+
references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
15+
) ;
16+
17+
-- insert script that 'copies' existing batch_job_params to batch_job_execution_params
18+
-- sets new params to identifying ones
19+
-- verified on h2,
20+
21+
INSERT INTO BATCH_JOB_EXECUTION_PARAMS
22+
( JOB_EXECUTION_ID , TYPE_CD, KEY_NAME, STRING_VAL, DATE_VAL, LONG_VAL, DOUBLE_VAL, IDENTIFYING )
23+
SELECT
24+
JE.JOB_EXECUTION_ID , JP.TYPE_CD , JP.KEY_NAME , JP.STRING_VAL , JP.DATE_VAL , JP.LONG_VAL , JP.DOUBLE_VAL , 1
25+
FROM
26+
BATCH_JOB_PARAMS JP,BATCH_JOB_EXECUTION JE
27+
WHERE
28+
JP.JOB_INSTANCE_ID = JE.JOB_INSTANCE_ID;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
-- create the requisite table
3+
4+
CREATE TABLE BATCH_JOB_EXECUTION_PARAMS (
5+
JOB_EXECUTION_ID BIGINT NOT NULL ,
6+
TYPE_CD VARCHAR(6) NOT NULL ,
7+
KEY_NAME VARCHAR(100) NOT NULL ,
8+
STRING_VAL VARCHAR(250) ,
9+
DATE_VAL TIMESTAMP DEFAULT NULL ,
10+
LONG_VAL BIGINT ,
11+
DOUBLE_VAL DOUBLE PRECISION ,
12+
IDENTIFYING CHAR(1) NOT NULL ,
13+
constraint JOB_EXEC_PARAMS_FK foreign key (JOB_EXECUTION_ID)
14+
references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
15+
) ;
16+
17+
-- insert script that 'copies' existing batch_job_params to batch_job_execution_params
18+
-- sets new params to identifying ones
19+
-- verified on h2,
20+
21+
INSERT INTO BATCH_JOB_EXECUTION_PARAMS
22+
( JOB_EXECUTION_ID , TYPE_CD, KEY_NAME, STRING_VAL, DATE_VAL, LONG_VAL, DOUBLE_VAL, IDENTIFYING )
23+
SELECT
24+
JE.JOB_EXECUTION_ID , JP.TYPE_CD , JP.KEY_NAME , JP.STRING_VAL , JP.DATE_VAL , JP.LONG_VAL , JP.DOUBLE_VAL , 1
25+
FROM
26+
BATCH_JOB_PARAMS JP,BATCH_JOB_EXECUTION JE
27+
WHERE
28+
JP.JOB_INSTANCE_ID = JE.JOB_INSTANCE_ID;

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

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,80 @@ public void write(List<? extends String> items) throws Exception {
486486
assertEquals(1, contribution.getWriteCount());
487487
assertEquals(0, contribution.getFilterCount());
488488
}
489+
490+
@Test
491+
// BATCH-2036
492+
public void testProcessFilterAndSkippableException() throws Exception {
493+
final List<String> processedItems = new ArrayList<String>();
494+
processor.setProcessorTransactional(false);
495+
processor.setProcessSkipPolicy(new AlwaysSkipItemSkipPolicy());
496+
processor.setItemProcessor(new ItemProcessor<String, String>() {
497+
@Override
498+
public String process(String item) throws Exception {
499+
processedItems.add(item);
500+
if (item.contains("fail")) {
501+
throw new IllegalArgumentException("Expected Skippable Exception!");
502+
}
503+
if (item.contains("skip")) {
504+
return null;
505+
}
506+
return item;
507+
}
508+
});
509+
processor.afterPropertiesSet();
510+
Chunk<String> inputs = new Chunk<String>(Arrays.asList("1", "2", "skip", "skip", "3", "fail", "fail", "4", "5"));
511+
try {
512+
processor.process(contribution, inputs);
513+
fail("Expected IllegalArgumentException");
514+
} catch (IllegalArgumentException e) {
515+
assertEquals("Expected Skippable Exception!", e.getMessage());
516+
}
517+
try {
518+
processor.process(contribution, inputs);
519+
fail("Expected IllegalArgumentException");
520+
} catch (IllegalArgumentException e) {
521+
assertEquals("Expected Skippable Exception!", e.getMessage());
522+
}
523+
processor.process(contribution, inputs);
524+
assertEquals(5, list.size());
525+
assertEquals("[1, 2, 3, 4, 5]", list.toString());
526+
assertEquals(2, contribution.getFilterCount());
527+
assertEquals(2, contribution.getProcessSkipCount());
528+
assertEquals(9, processedItems.size());
529+
assertEquals("[1, 2, skip, skip, 3, fail, fail, 4, 5]", processedItems.toString());
530+
}
531+
532+
@Test
533+
// BATCH-2036
534+
public void testProcessFilterAndSkippableExceptionNoRollback() throws Exception {
535+
final List<String> processedItems = new ArrayList<String>();
536+
processor.setProcessorTransactional(false);
537+
processor.setProcessSkipPolicy(new AlwaysSkipItemSkipPolicy());
538+
processor.setItemProcessor(new ItemProcessor<String, String>() {
539+
@Override
540+
public String process(String item) throws Exception {
541+
processedItems.add(item);
542+
if (item.contains("fail")) {
543+
throw new IllegalArgumentException("Expected Skippable Exception!");
544+
}
545+
if (item.contains("skip")) {
546+
return null;
547+
}
548+
return item;
549+
}
550+
});
551+
processor.setRollbackClassifier(new BinaryExceptionClassifier(Collections
552+
.<Class<? extends Throwable>> singleton(IllegalArgumentException.class), false));
553+
processor.afterPropertiesSet();
554+
Chunk<String> inputs = new Chunk<String>(Arrays.asList("1", "2", "skip", "skip", "3", "fail", "fail", "4", "5"));
555+
processor.process(contribution, inputs);
556+
assertEquals(5, list.size());
557+
assertEquals("[1, 2, 3, 4, 5]", list.toString());
558+
assertEquals(2, contribution.getFilterCount());
559+
assertEquals(2, contribution.getProcessSkipCount());
560+
assertEquals(9, processedItems.size());
561+
assertEquals("[1, 2, skip, skip, 3, fail, fail, 4, 5]", processedItems.toString());
562+
}
489563

490564
protected void processAndExpectPlannedRuntimeException(Chunk<String> chunk)
491565
throws Exception {

spring-batch-infrastructure-tests/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<parent>
88
<groupId>org.springframework.batch</groupId>
99
<artifactId>spring-batch-parent</artifactId>
10-
<version>3.0.0.BUILD-SNAPSHOT</version>
10+
<version>2.2.2.BUILD-SNAPSHOT</version>
1111
<relativePath>../spring-batch-parent</relativePath>
1212
</parent>
1313
<properties>
@@ -57,7 +57,7 @@
5757
<dependency>
5858
<groupId>org.springframework.batch</groupId>
5959
<artifactId>spring-batch-infrastructure</artifactId>
60-
<version>3.0.0.BUILD-SNAPSHOT</version>
60+
<version>2.2.2.BUILD-SNAPSHOT</version>
6161
</dependency>
6262
<dependency>
6363
<groupId>org.hsqldb</groupId>

spring-batch-infrastructure/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<parent>
1313
<groupId>org.springframework.batch</groupId>
1414
<artifactId>spring-batch-parent</artifactId>
15-
<version>3.0.0.BUILD-SNAPSHOT</version>
15+
<version>2.2.2.BUILD-SNAPSHOT</version>
1616
<relativePath>../spring-batch-parent</relativePath>
1717
</parent>
1818
<build>

spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/AbstractCursorItemReader.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ protected void doClose() throws Exception {
394394
* Execute the statement to open the cursor.
395395
*/
396396
@Override
397-
protected final void doOpen() throws Exception {
397+
protected void doOpen() throws Exception {
398398

399399
Assert.state(!initialized, "Stream is already initialized. Close before re-opening.");
400400
Assert.isNull(rs, "ResultSet still open! Close before re-opening.");

spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/HibernateItemWriter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public void setHibernateTemplate(HibernateOperations hibernateTemplate) {
8181
*
8282
* @param sessionFactory session factory to be used by the writer
8383
*/
84-
public final void setSessionFactory(SessionFactory sessionFactory) {
84+
public void setSessionFactory(SessionFactory sessionFactory) {
8585
this.sessionFactory = sessionFactory;
8686
}
8787

@@ -101,7 +101,7 @@ public void afterPropertiesSet() {
101101
* @see org.springframework.batch.item.ItemWriter#write(java.util.List)
102102
*/
103103
@Override
104-
public final void write(List<? extends T> items) {
104+
public void write(List<? extends T> items) {
105105
if(sessionFactory == null) {
106106
doWrite(hibernateTemplate, items);
107107
hibernateTemplate.flush();

spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JdbcPagingItemReader.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
* specified in {@link #setPageSize(int)}. Additional pages are requested when
5151
* needed as {@link #read()} method is called, returning an object corresponding
5252
* to current position. On restart it uses the last sort key value to locate the
53-
* first page to read (so it doesn't matter if the successfully processed itmes
53+
* first page to read (so it doesn't matter if the successfully processed items
5454
* have been removed or modified).
5555
* </p>
5656
*
@@ -94,6 +94,8 @@ public class JdbcPagingItemReader<T> extends AbstractPagingItemReader<T> impleme
9494
private String remainingPagesSql;
9595

9696
private Map<String, Object> startAfterValues;
97+
98+
private Map<String, Object> previousStartAfterValues;
9799

98100
private int fetchSize = VALUE_NOT_SET;
99101

@@ -210,6 +212,7 @@ protected void doReadPage() {
210212

211213
}
212214
else {
215+
previousStartAfterValues = startAfterValues;
213216
if (logger.isDebugEnabled()) {
214217
logger.debug("SQL used for reading remaining pages: [" + remainingPagesSql + "]");
215218
}
@@ -230,10 +233,20 @@ protected void doReadPage() {
230233
@Override
231234
public void update(ExecutionContext executionContext) throws ItemStreamException {
232235
super.update(executionContext);
233-
if (isSaveState() && startAfterValues != null) {
234-
executionContext.put(getExecutionContextKey(START_AFTER_VALUE), startAfterValues);
236+
if (isSaveState()) {
237+
if (isAtEndOfPage() && startAfterValues != null) {
238+
// restart on next page
239+
executionContext.put(getExecutionContextKey(START_AFTER_VALUE), startAfterValues);
240+
} else if (previousStartAfterValues != null) {
241+
// restart on current page
242+
executionContext.put(getExecutionContextKey(START_AFTER_VALUE), previousStartAfterValues);
243+
}
235244
}
236245
}
246+
247+
private boolean isAtEndOfPage() {
248+
return getCurrentItemCount() % getPageSize() == 0;
249+
}
237250

238251
@Override
239252
@SuppressWarnings("unchecked")

spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JpaItemWriter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public void afterPropertiesSet() throws Exception {
7676
* @see org.springframework.batch.item.ItemWriter#write(java.util.List)
7777
*/
7878
@Override
79-
public final void write(List<? extends T> items) {
79+
public void write(List<? extends T> items) {
8080
EntityManager entityManager = EntityManagerFactoryUtils.getTransactionalEntityManager(entityManagerFactory);
8181
if (entityManager == null) {
8282
throw new DataAccessResourceFailureException("Unable to obtain a transactional EntityManager");

spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/DerbyPagingQueryProvider.java

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,32 @@
3535
* @since 2.0
3636
*/
3737
public class DerbyPagingQueryProvider extends SqlWindowingPagingQueryProvider {
38-
39-
private String version;
38+
39+
private static final String MINIMAL_DERBY_VERSION = "10.4.1.3";
4040

4141
@Override
4242
public void init(DataSource dataSource) throws Exception {
4343
super.init(dataSource);
44-
version = JdbcUtils.extractDatabaseMetaData(dataSource, "getDatabaseProductVersion").toString();
45-
if ("10.4.1.3".compareTo(version) > 0) {
46-
throw new InvalidDataAccessResourceUsageException("Apache Derby version " + version + " is not supported by this class, Only version 10.4.1.3 or later is supported");
44+
String version = JdbcUtils.extractDatabaseMetaData(dataSource, "getDatabaseProductVersion").toString();
45+
if (!isDerbyVersionSupported(version)) {
46+
throw new InvalidDataAccessResourceUsageException("Apache Derby version " + version + " is not supported by this class, Only version " + MINIMAL_DERBY_VERSION + " or later is supported");
47+
}
48+
}
49+
50+
// derby version numbering is M.m.f.p [ {alpha|beta} ] see http://db.apache.org/derby/papers/versionupgrade.html#Basic+Numbering+Scheme
51+
private boolean isDerbyVersionSupported(String version) {
52+
String[] minimalVersionParts = MINIMAL_DERBY_VERSION.split("\\.");
53+
String[] versionParts = version.split("[\\. ]");
54+
for (int i = 0; i < minimalVersionParts.length; i++) {
55+
int minimalVersionPart = Integer.valueOf(minimalVersionParts[i]);
56+
int versionPart = Integer.valueOf(versionParts[i]);
57+
if (versionPart < minimalVersionPart) {
58+
return false;
59+
} else if (versionPart > minimalVersionPart) {
60+
return true;
61+
}
4762
}
63+
return true;
4864
}
4965

5066
@Override

0 commit comments

Comments
 (0)