From 7ecac1c2fff27a4f980deaf96c254fd9fa1f1b31 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Tue, 17 Jan 2023 11:21:56 +0100 Subject: [PATCH] Add default converters for java.util.Date parameter type Resolves #4297 Resolves #4270 --- .../support/DefaultBatchConfiguration.java | 7 ++- .../core/converter/AbstractDateConverter.java | 30 +++++++++++++ .../core/converter/DateToStringConverter.java | 38 ++++++++++++++++ .../DefaultJobParametersConverter.java | 19 +++++++- .../converter/JsonJobParametersConverter.java | 8 ++++ .../core/converter/StringToDateConverter.java | 39 ++++++++++++++++ .../support/JobExplorerFactoryBean.java | 10 +++-- .../repository/dao/JdbcJobExecutionDao.java | 16 +++++-- .../support/JobRepositoryFactoryBean.java | 10 ++++- .../converter/DateToStringConverterTest.java | 45 +++++++++++++++++++ .../DefaultJobParametersConverterTests.java | 44 +++++++----------- .../converter/StringToDateConverterTest.java | 45 +++++++++++++++++++ .../dao/JdbcJobExecutionDaoTests.java | 35 ++++++++++++--- 13 files changed, 300 insertions(+), 46 deletions(-) create mode 100644 spring-batch-core/src/main/java/org/springframework/batch/core/converter/AbstractDateConverter.java create mode 100644 spring-batch-core/src/main/java/org/springframework/batch/core/converter/DateToStringConverter.java create mode 100644 spring-batch-core/src/main/java/org/springframework/batch/core/converter/StringToDateConverter.java create mode 100644 spring-batch-core/src/test/java/org/springframework/batch/core/converter/DateToStringConverterTest.java create mode 100644 spring-batch-core/src/test/java/org/springframework/batch/core/converter/StringToDateConverterTest.java diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/DefaultBatchConfiguration.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/DefaultBatchConfiguration.java index 28b538b48..e0280ba26 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/DefaultBatchConfiguration.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/DefaultBatchConfiguration.java @@ -26,6 +26,8 @@ import org.apache.commons.logging.LogFactory; import org.springframework.batch.core.configuration.BatchConfigurationException; import org.springframework.batch.core.configuration.JobRegistry; +import org.springframework.batch.core.converter.DateToStringConverter; +import org.springframework.batch.core.converter.StringToDateConverter; import org.springframework.batch.core.explore.JobExplorer; import org.springframework.batch.core.explore.support.JobExplorerFactoryBean; import org.springframework.batch.core.launch.JobLauncher; @@ -375,7 +377,10 @@ public class DefaultBatchConfiguration implements ApplicationContextAware { * @return the {@link ConfigurableConversionService} to use. */ protected ConfigurableConversionService getConversionService() { - return new DefaultConversionService(); + DefaultConversionService conversionService = new DefaultConversionService(); + conversionService.addConverter(new DateToStringConverter()); + conversionService.addConverter(new StringToDateConverter()); + return conversionService; } } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/converter/AbstractDateConverter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/converter/AbstractDateConverter.java new file mode 100644 index 000000000..b0882ce1e --- /dev/null +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/converter/AbstractDateConverter.java @@ -0,0 +1,30 @@ +/* + * Copyright 2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.batch.core.converter; + +import java.time.format.DateTimeFormatter; + +/** + * Base class for {@link java.util.Date} converters. + * + * @author Mahmoud Ben Hassine + * @since 5.0.1 + */ +public class AbstractDateConverter { + + protected DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_INSTANT; + +} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/converter/DateToStringConverter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/converter/DateToStringConverter.java new file mode 100644 index 000000000..4fe91dc7a --- /dev/null +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/converter/DateToStringConverter.java @@ -0,0 +1,38 @@ +/* + * Copyright 2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.batch.core.converter; + +import java.util.Date; + +import org.springframework.core.convert.converter.Converter; + +/** + * {@link Converter} implementation from {@link java.util.Date} to {@link String}. + * + * This converter formats dates according to the + * {@link java.time.format.DateTimeFormatter#ISO_INSTANT} format. + * + * @author Mahmoud Ben Hassine + * @since 5.0.1 + */ +public class DateToStringConverter extends AbstractDateConverter implements Converter { + + @Override + public String convert(Date source) { + return super.dateTimeFormatter.format(source.toInstant()); + } + +} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/converter/DefaultJobParametersConverter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/converter/DefaultJobParametersConverter.java index 8af2b8764..298cccd02 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/converter/DefaultJobParametersConverter.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/converter/DefaultJobParametersConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 the original author or authors. + * Copyright 2006-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,6 +53,14 @@ import org.springframework.util.StringUtils; * service should be configured with a converter to and from string literals to job * parameter types. * + * By default, the Spring conversion service is augmented to support the conversion of the + * following types: + * + * + * * @author Dave Syer * @author Michael Minella * @author Mahmoud Ben Hassine @@ -60,7 +68,14 @@ import org.springframework.util.StringUtils; */ public class DefaultJobParametersConverter implements JobParametersConverter { - protected ConfigurableConversionService conversionService = new DefaultConversionService(); + protected ConfigurableConversionService conversionService; + + public DefaultJobParametersConverter() { + DefaultConversionService conversionService = new DefaultConversionService(); + conversionService.addConverter(new DateToStringConverter()); + conversionService.addConverter(new StringToDateConverter()); + this.conversionService = conversionService; + } /** * @see org.springframework.batch.core.converter.JobParametersConverter#getJobParameters(java.util.Properties) diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/converter/JsonJobParametersConverter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/converter/JsonJobParametersConverter.java index d51c10b15..92955f65f 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/converter/JsonJobParametersConverter.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/converter/JsonJobParametersConverter.java @@ -47,6 +47,14 @@ import org.springframework.batch.core.JobParameters; * service should be configured with a converter to and from string literals to job * parameter types. * + * By default, the Spring conversion service is augmented to support the conversion of the + * following types: + * + * + * * @author Mahmoud Ben Hassine * @since 5.0 * diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/converter/StringToDateConverter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/converter/StringToDateConverter.java new file mode 100644 index 000000000..90108abcd --- /dev/null +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/converter/StringToDateConverter.java @@ -0,0 +1,39 @@ +/* + * Copyright 2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.batch.core.converter; + +import java.time.Instant; +import java.util.Date; + +import org.springframework.core.convert.converter.Converter; + +/** + * {@link Converter} implementation from {@link String} to {@link java.util.Date}. + * + * This converter expects strings in the + * {@link java.time.format.DateTimeFormatter#ISO_INSTANT} format. + * + * @author Mahmoud Ben Hassine + * @since 5.0.1 + */ +public class StringToDateConverter extends AbstractDateConverter implements Converter { + + @Override + public Date convert(String source) { + return Date.from(super.dateTimeFormatter.parse(source, Instant::from)); + } + +} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/explore/support/JobExplorerFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/explore/support/JobExplorerFactoryBean.java index 36553fe50..a39780486 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/explore/support/JobExplorerFactoryBean.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/explore/support/JobExplorerFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,8 @@ import java.nio.charset.StandardCharsets; import javax.sql.DataSource; -import org.springframework.batch.core.explore.JobExplorer; +import org.springframework.batch.core.converter.DateToStringConverter; +import org.springframework.batch.core.converter.StringToDateConverter; import org.springframework.batch.core.repository.ExecutionContextSerializer; import org.springframework.batch.core.repository.dao.AbstractJdbcBatchMetadataDao; import org.springframework.batch.core.repository.dao.DefaultExecutionContextSerializer; @@ -164,7 +165,10 @@ public class JobExplorerFactoryBean extends AbstractJobExplorerFactoryBean imple } if (this.conversionService == null) { - this.conversionService = new DefaultConversionService(); + DefaultConversionService conversionService = new DefaultConversionService(); + conversionService.addConverter(new DateToStringConverter()); + conversionService.addConverter(new StringToDateConverter()); + this.conversionService = conversionService; } super.afterPropertiesSet(); diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JdbcJobExecutionDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JdbcJobExecutionDao.java index ea4ae2087..6ef4d11a3 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JdbcJobExecutionDao.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JdbcJobExecutionDao.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 the original author or authors. + * Copyright 2006-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,6 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.sql.Types; -import java.time.LocalDateTime; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -37,6 +36,8 @@ import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobInstance; import org.springframework.batch.core.JobParameter; import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.converter.DateToStringConverter; +import org.springframework.batch.core.converter.StringToDateConverter; import org.springframework.beans.factory.InitializingBean; import org.springframework.core.convert.support.ConfigurableConversionService; import org.springframework.core.convert.support.DefaultConversionService; @@ -106,7 +107,14 @@ public class JdbcJobExecutionDao extends AbstractJdbcBatchMetadataDao implements private DataFieldMaxValueIncrementer jobExecutionIncrementer; - private ConfigurableConversionService conversionService = new DefaultConversionService(); + private ConfigurableConversionService conversionService; + + public JdbcJobExecutionDao() { + DefaultConversionService conversionService = new DefaultConversionService(); + conversionService.addConverter(new DateToStringConverter()); + conversionService.addConverter(new StringToDateConverter()); + this.conversionService = conversionService; + } /** * Public setter for the exit message length in database. Do not set this if you @@ -127,7 +135,7 @@ public class JdbcJobExecutionDao extends AbstractJdbcBatchMetadataDao implements } /** - * Set the conversion service to use to convert job parameters from String literal to + * Set the conversion service to use to convert job parameters from String literals to * typed values and vice versa. */ public void setConversionService(@NonNull ConfigurableConversionService conversionService) { diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/JobRepositoryFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/JobRepositoryFactoryBean.java index 480028d58..86c3afe80 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/JobRepositoryFactoryBean.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/JobRepositoryFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,11 +20,14 @@ import java.lang.reflect.Field; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.sql.Types; + import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.batch.core.converter.DateToStringConverter; +import org.springframework.batch.core.converter.StringToDateConverter; import org.springframework.batch.core.repository.ExecutionContextSerializer; import org.springframework.batch.core.repository.dao.AbstractJdbcBatchMetadataDao; import org.springframework.batch.core.repository.dao.DefaultExecutionContextSerializer; @@ -235,7 +238,10 @@ public class JobRepositoryFactoryBean extends AbstractJobRepositoryFactoryBean i } if (this.conversionService == null) { - this.conversionService = new DefaultConversionService(); + DefaultConversionService conversionService = new DefaultConversionService(); + conversionService.addConverter(new DateToStringConverter()); + conversionService.addConverter(new StringToDateConverter()); + this.conversionService = conversionService; } super.afterPropertiesSet(); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/converter/DateToStringConverterTest.java b/spring-batch-core/src/test/java/org/springframework/batch/core/converter/DateToStringConverterTest.java new file mode 100644 index 000000000..0ab1be5dc --- /dev/null +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/converter/DateToStringConverterTest.java @@ -0,0 +1,45 @@ +/* + * Copyright 2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.batch.core.converter; + +import java.time.Instant; +import java.util.Date; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * Test class for {@link DateToStringConverter}. + * + * @author Mahmoud Ben Hassine + */ +class DateToStringConverterTest { + + private final DateToStringConverter converter = new DateToStringConverter(); + + @Test + void testConvert() { + // given + Date date = Date.from(Instant.EPOCH); + + // when + String converted = this.converter.convert(date); + + // then + Assertions.assertEquals("1970-01-01T00:00:00Z", converted); + } + +} \ No newline at end of file diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/converter/DefaultJobParametersConverterTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/converter/DefaultJobParametersConverterTests.java index 9f69a277f..f1dde5deb 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/converter/DefaultJobParametersConverterTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/converter/DefaultJobParametersConverterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 the original author or authors. + * Copyright 2006-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,33 +15,23 @@ */ package org.springframework.batch.core.converter; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.Properties; + +import org.junit.jupiter.api.Test; + +import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.JobParametersBuilder; +import org.springframework.core.convert.converter.Converter; +import org.springframework.core.convert.support.DefaultConversionService; +import org.springframework.util.StringUtils; + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; -import java.text.DateFormat; -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.text.NumberFormat; -import java.text.SimpleDateFormat; -import java.time.Instant; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.ZoneOffset; -import java.time.format.DateTimeFormatter; -import java.util.Date; -import java.util.Locale; -import java.util.Properties; - -import org.junit.jupiter.api.Test; -import org.springframework.batch.core.JobParameters; -import org.springframework.batch.core.JobParametersBuilder; -import org.springframework.core.convert.ConversionService; -import org.springframework.core.convert.converter.Converter; -import org.springframework.core.convert.support.DefaultConversionService; -import org.springframework.util.StringUtils; - /** * @author Dave Syer * @author Michael Minella @@ -55,7 +45,7 @@ class DefaultJobParametersConverterTests { @Test void testGetParametersIdentifyingWithIdentifyingKey() { String jobKey = "job.key=myKey,java.lang.String,true"; - String scheduleDate = "schedule.date=2008/01/23,java.util.Date,true"; + String scheduleDate = "schedule.date=2008-01-23T10:15:30Z,java.util.Date,true"; String vendorId = "vendor.id=33243243,java.lang.Long,true"; String[] args = new String[] { jobKey, scheduleDate, vendorId }; @@ -70,7 +60,7 @@ class DefaultJobParametersConverterTests { @Test void testGetParametersIdentifyingByDefault() { String jobKey = "job.key=myKey,java.lang.String"; - String scheduleDate = "schedule.date=2008/01/23,java.util.Date"; + String scheduleDate = "schedule.date=2008-01-23T10:15:30Z,java.util.Date"; String vendorId = "vendor.id=33243243,java.lang.Long"; String[] args = new String[] { jobKey, scheduleDate, vendorId }; @@ -85,7 +75,7 @@ class DefaultJobParametersConverterTests { @Test void testGetParametersNonIdentifying() { String jobKey = "job.key=myKey,java.lang.String,false"; - String scheduleDate = "schedule.date=2008/01/23,java.util.Date,false"; + String scheduleDate = "schedule.date=2008-01-23T10:15:30Z,java.util.Date,false"; String vendorId = "vendor.id=33243243,java.lang.Long,false"; String[] args = new String[] { jobKey, scheduleDate, vendorId }; @@ -100,7 +90,7 @@ class DefaultJobParametersConverterTests { @Test void testGetParametersMixed() { String jobKey = "job.key=myKey,java.lang.String,true"; - String scheduleDate = "schedule.date=2008/01/23,java.util.Date"; + String scheduleDate = "schedule.date=2008-01-23T10:15:30Z,java.util.Date"; String vendorId = "vendor.id=33243243,java.lang.Long,false"; String[] args = new String[] { jobKey, scheduleDate, vendorId }; diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/converter/StringToDateConverterTest.java b/spring-batch-core/src/test/java/org/springframework/batch/core/converter/StringToDateConverterTest.java new file mode 100644 index 000000000..db6e4abc6 --- /dev/null +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/converter/StringToDateConverterTest.java @@ -0,0 +1,45 @@ +/* + * Copyright 2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.batch.core.converter; + +import java.time.Instant; +import java.util.Date; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * Test class for {@link StringToDateConverter}. + * + * @author Mahmoud Ben Hassine + */ +class StringToDateConverterTest { + + private final StringToDateConverter converter = new StringToDateConverter(); + + @Test + void convert() { + // given + String date = "1970-01-01T00:00:00Z"; + + // when + Date converted = this.converter.convert(date); + + // then + Assertions.assertEquals(Date.from(Instant.EPOCH), converted); + } + +} \ No newline at end of file diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/JdbcJobExecutionDaoTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/JdbcJobExecutionDaoTests.java index c7f5d654a..c4f1b9bd1 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/JdbcJobExecutionDaoTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/JdbcJobExecutionDaoTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2022 the original author or authors. + * Copyright 2008-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,24 +17,19 @@ package org.springframework.batch.core.repository.dao; import java.util.Date; import java.util.HashMap; -import java.util.List; import java.util.Map; import javax.sql.DataSource; -import static org.junit.jupiter.api.Assertions.assertNull; - import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobParameter; import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.JobParametersBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; -import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import org.springframework.test.jdbc.JdbcTestUtils; import org.springframework.transaction.annotation.Transactional; @@ -109,4 +104,30 @@ public class JdbcJobExecutionDaoTests extends AbstractJobExecutionDaoTests { Assertions.assertEquals(0, JdbcTestUtils.countRowsInTable(jdbcTemplate, "BATCH_JOB_EXECUTION_PARAMS")); } + @Transactional + @Test + void testJobParametersPersistenceRoundTrip() { + // given + Date dateParameter = new Date(); + String stringParameter = "foo"; + long longParameter = 1L; + double doubleParameter = 2D; + JobParameters jobParameters = new JobParametersBuilder().addString("string", stringParameter) + .addLong("long", longParameter).addDouble("double", doubleParameter).addDate("date", dateParameter) + .toJobParameters(); + JobExecution execution = new JobExecution(jobInstance, jobParameters); + + // when + dao.saveJobExecution(execution); + execution = dao.getJobExecution(execution.getId()); + + // then + JobParameters parameters = execution.getJobParameters(); + Assertions.assertNotNull(parameters); + Assertions.assertEquals(dateParameter, parameters.getDate("date")); + Assertions.assertEquals(stringParameter, parameters.getString("string")); + Assertions.assertEquals(longParameter, parameters.getLong("long")); + Assertions.assertEquals(doubleParameter, parameters.getDouble("double")); + } + }