Skip to content

Commit fdd253a

Browse files
linhongchengfmbenhassine
linhongcheng
authored andcommitted
Fix retrieval of null job parameters of type long/double
Before this commit, a null job parameter of type long or double was retrieved as 0L or 0.0. This caused JobOperator.restart to create a new job instance instead of restarting the previous failed execution. This commit fixes how null job parameters of type long or double are retrieved from the database to correctly restart the same job instance. Issue #4087
1 parent 2bdf428 commit fdd253a

File tree

2 files changed

+36
-4
lines changed

2 files changed

+36
-4
lines changed

spring-batch-core-tests/src/test/java/org/springframework/batch/core/test/repository/MySQLJdbcJobRepositoryTests.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2021 the original author or authors.
2+
* Copyright 2020-2022 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.
@@ -110,6 +110,36 @@ public void testDateMillisecondPrecision() throws Exception {
110110
Assert.assertEquals(2, jobExecutions.size());
111111
}
112112

113+
/*
114+
* This test is for issue https://github.com/spring-projects/spring-batch/issues/4087:
115+
* A round trip from a `java.lang.Long` or `java.lang.Double` JobParameter that value is null to the database and back
116+
* again should preserve null. otherwise a different
117+
* job instance is created while the existing one should be used.
118+
*
119+
* This test ensures that round trip to the database with a `java.lang.Long` or `java.lang.Double`
120+
* parameter that value is null ends up with a single job instance (with two job executions)
121+
* being created and not two distinct job instances (with a job execution for
122+
* each one).
123+
*
124+
*/
125+
@Test
126+
public void testLongOrDoubleNullable() throws Exception {
127+
// given
128+
JobParameters jobParameters = new JobParametersBuilder()
129+
.addLong("attribute", null) // as same as Double type
130+
.toJobParameters();
131+
132+
// when
133+
JobExecution jobExecution = this.jobLauncher.run(this.job, jobParameters);
134+
this.jobOperator.restart(jobExecution.getId()); // should load the null value for java.lang.Long or java.lang.Double
135+
136+
// then
137+
List<Long> jobInstances = this.jobOperator.getJobInstances("job", 0, 100);
138+
Assert.assertEquals(1, jobInstances.size());
139+
List<Long> jobExecutions = this.jobOperator.getExecutions(jobInstances.get(0));
140+
Assert.assertEquals(2, jobExecutions.size());
141+
}
142+
113143
@Configuration
114144
@EnableBatchProcessing
115145
static class TestConfiguration {

spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JdbcJobExecutionDao.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2006-2019 the original author or authors.
2+
* Copyright 2006-2022 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.
@@ -374,9 +374,11 @@ public void processRow(ResultSet rs) throws SQLException {
374374
if (type == ParameterType.STRING) {
375375
value = new JobParameter(rs.getString(4), rs.getString(8).equalsIgnoreCase("Y"));
376376
} else if (type == ParameterType.LONG) {
377-
value = new JobParameter(rs.getLong(6), rs.getString(8).equalsIgnoreCase("Y"));
377+
long longValue = rs.getLong(6);
378+
value = new JobParameter(rs.wasNull() ? null : longValue, rs.getString(8).equalsIgnoreCase("Y"));
378379
} else if (type == ParameterType.DOUBLE) {
379-
value = new JobParameter(rs.getDouble(7), rs.getString(8).equalsIgnoreCase("Y"));
380+
double doubleValue = rs.getDouble(7);
381+
value = new JobParameter(rs.wasNull() ? null : doubleValue, rs.getString(8).equalsIgnoreCase("Y"));
380382
} else if (type == ParameterType.DATE) {
381383
value = new JobParameter(rs.getTimestamp(5), rs.getString(8).equalsIgnoreCase("Y"));
382384
}

0 commit comments

Comments
 (0)