From 43ac1f12cfd651abe68a94c3fdde235e3ca5135f Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Tue, 29 Apr 2025 08:57:30 +0200 Subject: [PATCH] Remove deprecated APIs scheduled for removal in v6 Resolves #4819 --- .../annotation/BatchRegistrar.java | 10 - .../annotation/EnableBatchProcessing.java | 10 +- .../support/DefaultBatchConfiguration.java | 63 +- .../support/JobRegistryBeanPostProcessor.java | 176 --- ...JobRegistrySmartInitializingSingleton.java | 5 +- .../xml/JobRepositoryParser.java | 7 +- .../xml/StepParserStepFactoryBean.java | 20 +- .../support/JobExplorerFactoryBean.java | 18 +- .../batch/core/job/builder/JobBuilder.java | 12 +- .../core/job/builder/JobBuilderHelper.java | 27 +- .../core/listener/ChunkListenerSupport.java | 43 - .../listener/JobExecutionListenerSupport.java | 37 - .../core/listener/SkipListenerSupport.java | 43 - .../StepExecutionListenerSupport.java | 41 - .../dao/JdbcExecutionContextDao.java | 19 +- .../repository/dao/JdbcJobInstanceDao.java | 13 +- .../support/JobRepositoryFactoryBean.java | 27 +- .../builder/AbstractTaskletStepBuilder.java | 29 +- .../batch/core/step/builder/StepBuilder.java | 67 +- .../core/step/builder/StepBuilderHelper.java | 25 +- .../core/step/builder/TaskletStepBuilder.java | 14 +- .../step/factory/SimpleStepFactoryBean.java | 18 +- .../configuration/xml/spring-batch-5.0.xsd | 1368 +++++++++++++++++ .../core/configuration/xml/spring-batch.xsd | 26 +- .../JobRegistryBeanPostProcessorTests.java | 125 -- .../xml/StepParserStepFactoryBeanTests.java | 5 +- .../configuration/xml/StepParserTests.java | 4 +- .../JobRepositoryFactoryBeanTests.java | 46 +- .../core/step/builder/StepBuilderTests.java | 7 +- .../step/item/SimpleStepFactoryBeanTests.java | 3 +- ...syncChunkOrientedStepIntegrationTests.java | 3 +- .../step/tasklet/AsyncTaskletStepTests.java | 3 +- .../JobRegistryIntegrationTests-context.xml | 2 +- .../configuration/support/test-context.xml | 2 +- .../support/trivial-context-autoregister.xml | 2 +- .../xml/JobRegistryJobParserTests-context.xml | 2 +- .../xml/JobRepositoryParserTests-context.xml | 3 +- ...epParserTaskletAttributesTests-context.xml | 2 +- ...tStepAllowStartIfCompleteTests-context.xml | 2 +- .../launch/support/launcher-with-locator.xml | 2 +- ...onment-with-registry-and-auto-register.xml | 2 +- .../resources/simple-job-launcher-context.xml | 2 +- .../modules/ROOT/pages/appendix.adoc | 10 +- .../ROOT/pages/job/advanced-meta-data.adoc | 54 +- .../item-reader-writer-implementations.adoc | 31 +- .../modules/ROOT/pages/scalability.adoc | 23 - .../batch/item/data/MongoItemReader.java | 266 ---- .../batch/item/data/MongoItemWriter.java | 15 +- .../item/data/MongoPagingItemReader.java | 193 ++- .../batch/item/data/Neo4jItemReader.java | 217 --- .../batch/item/data/Neo4jItemWriter.java | 126 -- .../data/builder/MongoItemReaderBuilder.java | 299 ---- .../data/builder/MongoItemWriterBuilder.java | 19 +- .../builder/MongoPagingItemReaderBuilder.java | 34 +- .../data/builder/Neo4jItemReaderBuilder.java | 265 ---- .../data/builder/Neo4jItemWriterBuilder.java | 81 - .../database/support/SqlPagingQueryUtils.java | 60 +- .../SqlWindowingPagingQueryProvider.java | 130 -- .../listener/RepeatListenerSupport.java | 53 - .../support/TaskExecutorRepeatTemplate.java | 21 +- .../support/SystemPropertyInitializer.java | 71 - .../batch/item/data/MongoItemWriterTests.java | 10 +- .../batch/item/data/Neo4jItemReaderTests.java | 171 --- .../batch/item/data/Neo4jItemWriterTests.java | 115 -- .../builder/MongoItemWriterBuilderTests.java | 6 +- .../builder/Neo4jItemReaderBuilderTests.java | 258 ---- .../builder/Neo4jItemWriterBuilderTests.java | 91 -- .../SqlWindowingPagingQueryProviderTests.java | 77 - ...ecutorRepeatTemplateAsynchronousTests.java | 3 +- ...orRepeatTemplateBulkAsynchronousTests.java | 104 +- .../TaskExecutorRepeatTemplateTests.java | 13 +- .../SystemPropertyInitializerTests.java | 62 - .../RemoteChunkingManagerStepBuilder.java | 28 +- .../RemotePartitioningManagerStepBuilder.java | 28 +- .../RemotePartitioningWorkerStepBuilder.java | 49 +- spring-batch-samples/README.md | 2 +- .../main/resources/data-source-context.xml | 1 - .../misc/jmx/adhoc-job-launcher-context.xml | 4 +- .../resources/simple-job-launcher-context.xml | 4 +- 79 files changed, 1635 insertions(+), 3694 deletions(-) delete mode 100644 spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/JobRegistryBeanPostProcessor.java delete mode 100644 spring-batch-core/src/main/java/org/springframework/batch/core/listener/ChunkListenerSupport.java delete mode 100644 spring-batch-core/src/main/java/org/springframework/batch/core/listener/JobExecutionListenerSupport.java delete mode 100644 spring-batch-core/src/main/java/org/springframework/batch/core/listener/SkipListenerSupport.java delete mode 100644 spring-batch-core/src/main/java/org/springframework/batch/core/listener/StepExecutionListenerSupport.java create mode 100644 spring-batch-core/src/main/resources/org/springframework/batch/core/configuration/xml/spring-batch-5.0.xsd delete mode 100644 spring-batch-core/src/test/java/org/springframework/batch/core/configuration/support/JobRegistryBeanPostProcessorTests.java delete mode 100644 spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoItemReader.java delete mode 100644 spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/Neo4jItemReader.java delete mode 100644 spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/Neo4jItemWriter.java delete mode 100644 spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/MongoItemReaderBuilder.java delete mode 100644 spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/Neo4jItemReaderBuilder.java delete mode 100644 spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/Neo4jItemWriterBuilder.java delete mode 100644 spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlWindowingPagingQueryProvider.java delete mode 100644 spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/listener/RepeatListenerSupport.java delete mode 100644 spring-batch-infrastructure/src/main/java/org/springframework/batch/support/SystemPropertyInitializer.java delete mode 100644 spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/Neo4jItemReaderTests.java delete mode 100644 spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/Neo4jItemWriterTests.java delete mode 100644 spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/Neo4jItemReaderBuilderTests.java delete mode 100644 spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/Neo4jItemWriterBuilderTests.java delete mode 100644 spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/SqlWindowingPagingQueryProviderTests.java delete mode 100644 spring-batch-infrastructure/src/test/java/org/springframework/batch/support/SystemPropertyInitializerTests.java diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/BatchRegistrar.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/BatchRegistrar.java index 3d23f6bcf..073ef836d 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/BatchRegistrar.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/BatchRegistrar.java @@ -111,11 +111,6 @@ class BatchRegistrar implements ImportBeanDefinitionRegistrar { beanDefinitionBuilder.addPropertyReference("serializer", executionContextSerializerRef); } - String lobHandlerRef = batchAnnotation.lobHandlerRef(); - if (registry.containsBeanDefinition(lobHandlerRef)) { - beanDefinitionBuilder.addPropertyReference("lobHandler", lobHandlerRef); - } - String conversionServiceRef = batchAnnotation.conversionServiceRef(); if (registry.containsBeanDefinition(conversionServiceRef)) { beanDefinitionBuilder.addPropertyReference("conversionService", conversionServiceRef); @@ -178,11 +173,6 @@ class BatchRegistrar implements ImportBeanDefinitionRegistrar { beanDefinitionBuilder.addPropertyReference("serializer", executionContextSerializerRef); } - String lobHandlerRef = batchAnnotation.lobHandlerRef(); - if (registry.containsBeanDefinition(lobHandlerRef)) { - beanDefinitionBuilder.addPropertyReference("lobHandler", lobHandlerRef); - } - String conversionServiceRef = batchAnnotation.conversionServiceRef(); if (registry.containsBeanDefinition(conversionServiceRef)) { beanDefinitionBuilder.addPropertyReference("conversionService", conversionServiceRef); diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/EnableBatchProcessing.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/EnableBatchProcessing.java index 27239d36c..6e2740079 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/EnableBatchProcessing.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/EnableBatchProcessing.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2024 the original author or authors. + * Copyright 2012-2025 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. @@ -238,14 +238,6 @@ public @interface EnableBatchProcessing { */ String jobKeyGeneratorRef() default "jobKeyGenerator"; - /** - * The large object handler to use in job repository and job explorer. - * @return the bean name of the lob handler to use. Defaults to {@literal lobHandler}. - * @deprecated Since 5.2 with no replacement. Scheduled for removal in v6 - */ - @Deprecated(since = "5.2.0", forRemoval = true) - String lobHandlerRef() default "lobHandler"; - /** * The type of large objects. * @return the type of large objects. 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 67df9fd41..484809fb2 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2024 the original author or authors. + * Copyright 2012-2025 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. @@ -67,8 +67,6 @@ import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.support.MetaDataAccessException; import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer; -import org.springframework.jdbc.support.lob.DefaultLobHandler; -import org.springframework.jdbc.support.lob.LobHandler; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.Isolation; @@ -85,7 +83,8 @@ import org.springframework.transaction.annotation.Isolation; *
  • a {@link JobLauncher} named "jobLauncher"
  • *
  • a {@link JobRegistry} named "jobRegistry"
  • *
  • a {@link JobOperator} named "JobOperator"
  • - *
  • a {@link JobRegistryBeanPostProcessor} named "jobRegistryBeanPostProcessor"
  • + *
  • a {@link JobRegistrySmartInitializingSingleton} named + * "jobRegistrySmartInitializingSingleton"
  • *
  • a {@link org.springframework.batch.core.scope.StepScope} named "stepScope"
  • *
  • a {@link org.springframework.batch.core.scope.JobScope} named "jobScope"
  • * @@ -137,7 +136,6 @@ public class DefaultBatchConfiguration implements ApplicationContextAware { jobRepositoryFactoryBean.setSerializer(getExecutionContextSerializer()); jobRepositoryFactoryBean.setConversionService(getConversionService()); jobRepositoryFactoryBean.setJdbcOperations(getJdbcOperations()); - jobRepositoryFactoryBean.setLobHandler(getLobHandler()); jobRepositoryFactoryBean.setCharset(getCharset()); jobRepositoryFactoryBean.setMaxVarCharLength(getMaxVarCharLength()); jobRepositoryFactoryBean.setIsolationLevelForCreateEnum(getIsolationLevelForCreate()); @@ -150,17 +148,6 @@ public class DefaultBatchConfiguration implements ApplicationContextAware { } } - /** - * Define a job launcher. - * @return a job launcher - * @throws BatchConfigurationException if unable to configure the default job launcher - * @deprecated Since 5.2. Use {@link #jobLauncher(JobRepository)} instead - */ - @Deprecated(forRemoval = true) - public JobLauncher jobLauncher() throws BatchConfigurationException { - return jobLauncher(jobRepository()); - } - /** * Define a job launcher bean. * @param jobRepository the job repository @@ -191,7 +178,6 @@ public class DefaultBatchConfiguration implements ApplicationContextAware { jobExplorerFactoryBean.setJobKeyGenerator(getJobKeyGenerator()); jobExplorerFactoryBean.setCharset(getCharset()); jobExplorerFactoryBean.setTablePrefix(getTablePrefix()); - jobExplorerFactoryBean.setLobHandler(getLobHandler()); jobExplorerFactoryBean.setConversionService(getConversionService()); jobExplorerFactoryBean.setSerializer(getExecutionContextSerializer()); try { @@ -208,18 +194,6 @@ public class DefaultBatchConfiguration implements ApplicationContextAware { return new MapJobRegistry(); } - /** - * Define a job operator. - * @return a job operator - * @throws BatchConfigurationException if unable to configure the default job operator - * @deprecated Since 5.2. Use - * {@link #jobOperator(JobRepository, JobExplorer, JobRegistry, JobLauncher)} instead - */ - @Deprecated(forRemoval = true) - public JobOperator jobOperator() throws BatchConfigurationException { - return jobOperator(jobRepository(), jobExplorer(), jobRegistry(), jobLauncher()); - } - /** * Define a job operator bean. * @param jobRepository a job repository @@ -249,26 +223,6 @@ public class DefaultBatchConfiguration implements ApplicationContextAware { } } - /** - * Defines a {@link JobRegistryBeanPostProcessor}. - * @return a {@link JobRegistryBeanPostProcessor} - * @throws BatchConfigurationException if unable to register the bean - * @since 5.1 - * @deprecated Use {@link #jobRegistrySmartInitializingSingleton(JobRegistry)} instead - */ - @Deprecated(forRemoval = true) - public JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor() throws BatchConfigurationException { - JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor = new JobRegistryBeanPostProcessor(); - jobRegistryBeanPostProcessor.setJobRegistry(jobRegistry()); - try { - jobRegistryBeanPostProcessor.afterPropertiesSet(); - return jobRegistryBeanPostProcessor; - } - catch (Exception e) { - throw new BatchConfigurationException("Unable to configure the default job registry BeanPostProcessor", e); - } - } - /** * Define a {@link JobRegistrySmartInitializingSingleton} bean. * @param jobRegistry the job registry to populate @@ -388,17 +342,6 @@ public class DefaultBatchConfiguration implements ApplicationContextAware { return StandardCharsets.UTF_8; } - /** - * A special handler for large objects. The default is usually fine, except for some - * (usually older) versions of Oracle. - * @return the {@link LobHandler} to use - * @deprecated Since 5.2 with no replacement. Scheduled for removal in v6 - */ - @Deprecated(since = "5.2.0", forRemoval = true) - protected LobHandler getLobHandler() { - return new DefaultLobHandler(); - } - /** * Return the {@link JdbcOperations}. If this property is not overridden, a new * {@link JdbcTemplate} will be created for the configured data source by default. diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/JobRegistryBeanPostProcessor.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/JobRegistryBeanPostProcessor.java deleted file mode 100644 index 1f6ba7acf..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/JobRegistryBeanPostProcessor.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2006-2024 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.configuration.support; - -import java.util.Collection; -import java.util.HashSet; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.batch.core.Job; -import org.springframework.batch.core.configuration.DuplicateJobException; -import org.springframework.batch.core.configuration.JobLocator; -import org.springframework.batch.core.configuration.JobRegistry; -import org.springframework.beans.BeansException; -import org.springframework.beans.FatalBeanException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.util.Assert; - -/** - * A {@link BeanPostProcessor} that registers {@link Job} beans with a - * {@link JobRegistry}. Include a bean of this type along with your job configuration and - * use the same {@link JobRegistry} as a {@link JobLocator} when you need to locate a - * {@link Job} to launch. - *

    - * An alternative to this class is {@link JobRegistrySmartInitializingSingleton}, which is - * recommended in cases where this class may cause early bean initializations. You must - * include at most one of either of them as a bean. - * - * @deprecated since 5.2 in favor of {@link JobRegistrySmartInitializingSingleton}. - * @author Dave Syer - * @author Mahmoud Ben Hassine - * - */ -@Deprecated(since = "5.2") -public class JobRegistryBeanPostProcessor - implements BeanPostProcessor, BeanFactoryAware, InitializingBean, DisposableBean { - - private static final Log logger = LogFactory.getLog(JobRegistryBeanPostProcessor.class); - - // It doesn't make sense for this to have a default value... - private JobRegistry jobRegistry = null; - - private final Collection jobNames = new HashSet<>(); - - private String groupName = null; - - private DefaultListableBeanFactory beanFactory; - - /** - * The group name for jobs registered by this component. Optional (defaults to null, - * which means that jobs are registered with their bean names). Useful where there is - * a hierarchy of application contexts all contributing to the same - * {@link JobRegistry}: child contexts can then define an instance with a unique group - * name to avoid clashes between job names. - * @param groupName the groupName to set - */ - public void setGroupName(String groupName) { - this.groupName = groupName; - } - - /** - * Injection setter for {@link JobRegistry}. - * @param jobRegistry the jobConfigurationRegistry to set - */ - public void setJobRegistry(JobRegistry jobRegistry) { - this.jobRegistry = jobRegistry; - } - - @Override - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - if (beanFactory instanceof DefaultListableBeanFactory) { - this.beanFactory = (DefaultListableBeanFactory) beanFactory; - } - } - - /** - * Make sure the registry is set before use. - * - * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() - */ - @Override - public void afterPropertiesSet() throws Exception { - Assert.state(jobRegistry != null, "JobRegistry must not be null"); - } - - /** - * Unregister all the {@link Job} instances that were registered by this post - * processor. - * @see org.springframework.beans.factory.DisposableBean#destroy() - */ - @Override - public void destroy() throws Exception { - for (String name : jobNames) { - if (logger.isDebugEnabled()) { - logger.debug("Unregistering job: " + name); - } - jobRegistry.unregister(name); - } - jobNames.clear(); - } - - /** - * If the bean is an instance of {@link Job}, then register it. - * @throws FatalBeanException if there is a {@link DuplicateJobException}. - * - * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, - * java.lang.String) - */ - @Override - public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - if (bean instanceof Job job) { - try { - String groupName = this.groupName; - if (beanFactory != null && beanFactory.containsBean(beanName)) { - groupName = getGroupName(beanFactory.getBeanDefinition(beanName), job); - } - job = groupName == null ? job : new GroupAwareJob(groupName, job); - ReferenceJobFactory jobFactory = new ReferenceJobFactory(job); - String name = jobFactory.getJobName(); - if (logger.isDebugEnabled()) { - logger.debug("Registering job: " + name); - } - jobRegistry.register(jobFactory); - jobNames.add(name); - } - catch (DuplicateJobException e) { - throw new FatalBeanException("Cannot register job configuration", e); - } - return job; - } - return bean; - } - - /** - * Determine a group name for the job to be registered. The default implementation - * returns the {@link #setGroupName(String) groupName} configured. Provides an - * extension point for specialised subclasses. - * @param beanDefinition the bean definition for the job - * @param job the job - * @return a group name for the job (or null if not needed) - */ - protected String getGroupName(BeanDefinition beanDefinition, Job job) { - return groupName; - } - - /** - * Do nothing. - * - * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, - * java.lang.String) - */ - @Override - public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { - return bean; - } - -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/JobRegistrySmartInitializingSingleton.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/JobRegistrySmartInitializingSingleton.java index ede418cf2..bd6f5b9a4 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/JobRegistrySmartInitializingSingleton.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/JobRegistrySmartInitializingSingleton.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 the original author or authors. + * Copyright 2024-2025 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. @@ -42,9 +42,6 @@ import org.springframework.util.Assert; * {@link JobRegistry}. Include a bean of this type along with your job configuration and * use the same {@link JobRegistry} as a {@link JobLocator} when you need to locate a * {@link Job} to launch. - *

    - * This class is an alternative to {@link JobRegistryBeanPostProcessor} and prevents early - * bean initializations. You must include at most one of either of them as a bean. * * @author Henning Pƶttker * @since 5.1.1 diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/JobRepositoryParser.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/JobRepositoryParser.java index be8808756..bbe403a11 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/JobRepositoryParser.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/JobRepositoryParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 the original author or authors. + * Copyright 2006-2025 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. @@ -77,8 +77,6 @@ public class JobRepositoryParser extends AbstractSingleBeanDefinitionParser { String maxVarCharLength = element.getAttribute("max-varchar-length"); - String lobHandler = element.getAttribute("lob-handler"); - String serializer = element.getAttribute("serializer"); String conversionService = element.getAttribute("conversion-service"); @@ -97,9 +95,6 @@ public class JobRepositoryParser extends AbstractSingleBeanDefinitionParser { if (StringUtils.hasText(tablePrefix)) { builder.addPropertyValue("tablePrefix", tablePrefix); } - if (StringUtils.hasText(lobHandler)) { - builder.addPropertyReference("lobHandler", lobHandler); - } if (StringUtils.hasText(maxVarCharLength)) { builder.addPropertyValue("maxVarCharLength", maxVarCharLength); } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/StepParserStepFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/StepParserStepFactoryBean.java index 7b18458ee..187bda9a3 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/StepParserStepFactoryBean.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/StepParserStepFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2025 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. @@ -185,8 +185,6 @@ public class StepParserStepFactoryBean implements FactoryBean, BeanN private TaskExecutor taskExecutor; - private Integer throttleLimit; - private ItemReader itemReader; private ItemProcessor itemProcessor; @@ -473,9 +471,6 @@ public class StepParserStepFactoryBean implements FactoryBean, BeanN } builder.taskExecutor(taskExecutor); - if (throttleLimit != null) { - builder.throttleLimit(throttleLimit); - } builder.transactionManager(transactionManager); if (transactionTimeout != null || propagation != null || isolation != null || noRollbackExceptionClasses != null) { @@ -992,19 +987,6 @@ public class StepParserStepFactoryBean implements FactoryBean, BeanN this.taskExecutor = taskExecutor; } - /** - * Public setter for the throttle limit. This limits the number of tasks queued for - * concurrent processing to prevent thread pools from being overwhelmed. Defaults to - * {@link TaskExecutorRepeatTemplate#DEFAULT_THROTTLE_LIMIT}. - * @param throttleLimit The throttle limit to set. - * @deprecated since 5.0, scheduled for removal in 6.0. This API is not intended for - * end users anyway. It is only used by the XML namespace parser. - */ - @Deprecated(since = "5.0", forRemoval = true) - public void setThrottleLimit(Integer throttleLimit) { - this.throttleLimit = throttleLimit; - } - /** * @param itemReader The {@link ItemReader} to set. */ 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 9d3e24dae..49f5661e6 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-2024 the original author or authors. + * Copyright 2002-2025 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. @@ -51,7 +51,6 @@ import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.support.incrementer.AbstractDataFieldMaxValueIncrementer; import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer; -import org.springframework.jdbc.support.lob.LobHandler; import org.springframework.lang.NonNull; import org.springframework.util.Assert; @@ -81,8 +80,6 @@ public class JobExplorerFactoryBean extends AbstractJobExplorerFactoryBean imple private JobKeyGenerator jobKeyGenerator; - private LobHandler lobHandler; - private ExecutionContextSerializer serializer; private Charset charset = StandardCharsets.UTF_8; @@ -138,18 +135,6 @@ public class JobExplorerFactoryBean extends AbstractJobExplorerFactoryBean imple this.jobKeyGenerator = jobKeyGenerator; } - /** - * The lob handler to use when saving {@link ExecutionContext} instances. Defaults to - * {@code null}, which works for most databases. - * @param lobHandler Large object handler for saving an - * {@link org.springframework.batch.item.ExecutionContext}. - * @deprecated Since 5.2 with no replacement. Scheduled for removal in v6 - */ - @Deprecated(since = "5.2.0", forRemoval = true) - public void setLobHandler(LobHandler lobHandler) { - this.lobHandler = lobHandler; - } - /** * Sets the {@link Charset} to use when deserializing the execution context. Defaults * to "UTF-8". Must not be {@code null}. @@ -210,7 +195,6 @@ public class JobExplorerFactoryBean extends AbstractJobExplorerFactoryBean imple protected ExecutionContextDao createExecutionContextDao() throws Exception { JdbcExecutionContextDao dao = new JdbcExecutionContextDao(); dao.setJdbcTemplate(jdbcOperations); - dao.setLobHandler(lobHandler); dao.setTablePrefix(tablePrefix); dao.setSerializer(serializer); dao.setCharset(charset); diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/JobBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/JobBuilder.java index 6ea482318..85f44a1a3 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/JobBuilder.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/JobBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2025 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. @@ -30,16 +30,6 @@ import org.springframework.batch.core.repository.JobRepository; */ public class JobBuilder extends JobBuilderHelper { - /** - * Create a new builder for a job with the given name. - * @param name the name of the job - * @deprecated use {@link JobBuilder#JobBuilder(String, JobRepository)} - */ - @Deprecated(since = "5.0", forRemoval = true) - public JobBuilder(String name) { - super(name); - } - /** * Create a new builder for a job with the given name. * @param name the name of the job diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/JobBuilderHelper.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/JobBuilderHelper.java index cacf2eab6..dee585863 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/JobBuilderHelper.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/JobBuilderHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2025 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. @@ -54,17 +54,6 @@ public abstract class JobBuilderHelper> { private final CommonJobProperties properties; - /** - * Create a new {@link JobBuilderHelper}. - * @param name the job name - * @deprecated use {@link JobBuilderHelper#JobBuilderHelper(String, JobRepository)} - */ - @Deprecated(since = "5.1", forRemoval = true) - public JobBuilderHelper(String name) { - this.properties = new CommonJobProperties(); - properties.name = name; - } - /** * Create a new {@link JobBuilderHelper}. * @param name the job name @@ -110,20 +99,6 @@ public abstract class JobBuilderHelper> { return result; } - /** - * Sets the job repository for the job. - * @param jobRepository the job repository (mandatory) - * @return this to enable fluent chaining - * @deprecated use {@link JobBuilderHelper#JobBuilderHelper(String, JobRepository)} - */ - @Deprecated(since = "5.1", forRemoval = true) - public B repository(JobRepository jobRepository) { - properties.jobRepository = jobRepository; - @SuppressWarnings("unchecked") - B result = (B) this; - return result; - } - /** * Sets the job observation convention. * @param observationConvention the job observation convention (optional) diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/ChunkListenerSupport.java b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/ChunkListenerSupport.java deleted file mode 100644 index 79d742240..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/ChunkListenerSupport.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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. - * 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.listener; - -import org.springframework.batch.core.ChunkListener; -import org.springframework.batch.core.scope.context.ChunkContext; - -/** - * Basic support implementation of {@link ChunkListener} - * - * @author Lucas Ward - * @author Michael Minella - * @deprecated as of 5.0, in favor of the default methods on the {@link ChunkListener} - */ -@Deprecated -public class ChunkListenerSupport implements ChunkListener { - - @Override - public void afterChunk(ChunkContext context) { - } - - @Override - public void beforeChunk(ChunkContext context) { - } - - @Override - public void afterChunkError(ChunkContext context) { - } - -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/JobExecutionListenerSupport.java b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/JobExecutionListenerSupport.java deleted file mode 100644 index fe54e5a6b..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/JobExecutionListenerSupport.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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. - * 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.listener; - -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobExecutionListener; - -/** - * @author Dave Syer - * @deprecated as of 5.0, in favor of the default methods on the - * {@link JobExecutionListener} - */ -@Deprecated -public class JobExecutionListenerSupport implements JobExecutionListener { - - @Override - public void afterJob(JobExecution jobExecution) { - } - - @Override - public void beforeJob(JobExecution jobExecution) { - } - -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/SkipListenerSupport.java b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/SkipListenerSupport.java deleted file mode 100644 index 00001e2ee..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/SkipListenerSupport.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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. - * 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.listener; - -import org.springframework.batch.core.SkipListener; - -/** - * Basic no-op implementations of all {@link SkipListener} implementations. - * - * @author Dave Syer - * @author Mahmoud Ben Hassine - * @deprecated as of v5.0 in favor of the default methods in {@link SkipListener}. - * - */ -@Deprecated -public class SkipListenerSupport implements SkipListener { - - @Override - public void onSkipInRead(Throwable t) { - } - - @Override - public void onSkipInWrite(S item, Throwable t) { - } - - @Override - public void onSkipInProcess(T item, Throwable t) { - } - -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/StepExecutionListenerSupport.java b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/StepExecutionListenerSupport.java deleted file mode 100644 index bd4bedb07..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/StepExecutionListenerSupport.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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. - * 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.listener; - -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.StepExecutionListener; -import org.springframework.lang.Nullable; - -/** - * @author Dave Syer - * @deprecated as of 5.0, in favor of the default methods on the - * {@link StepExecutionListener} - */ -@Deprecated -public class StepExecutionListenerSupport implements StepExecutionListener { - - @Nullable - @Override - public ExitStatus afterStep(StepExecution stepExecution) { - return null; - } - - @Override - public void beforeStep(StepExecution stepExecution) { - } - -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JdbcExecutionContextDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JdbcExecutionContextDao.java index 07915965c..47b8b40c1 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JdbcExecutionContextDao.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JdbcExecutionContextDao.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2024 the original author or authors. + * Copyright 2006-2025 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. @@ -40,8 +40,6 @@ import org.springframework.batch.item.ExecutionContext; import org.springframework.core.serializer.Serializer; import org.springframework.jdbc.core.BatchPreparedStatementSetter; import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.support.lob.DefaultLobHandler; -import org.springframework.jdbc.support.lob.LobHandler; import org.springframework.lang.NonNull; import org.springframework.util.Assert; @@ -110,8 +108,6 @@ public class JdbcExecutionContextDao extends AbstractJdbcBatchMetadataDao implem private int shortContextLength = DEFAULT_MAX_VARCHAR_LENGTH; - private LobHandler lobHandler = new DefaultLobHandler(); - private ExecutionContextSerializer serializer = new DefaultExecutionContextSerializer(); private final Lock lock = new ReentrantLock(); @@ -268,15 +264,6 @@ public class JdbcExecutionContextDao extends AbstractJdbcBatchMetadataDao implem getJdbcTemplate().update(getQuery(DELETE_STEP_EXECUTION_CONTEXT), stepExecution.getId()); } - /** - * @deprecated Since 5.2 with no replacement. Scheduled for removal in v6 - * @param lobHandler the lob handler to use - */ - @Deprecated(since = "5.2.0", forRemoval = true) - public void setLobHandler(LobHandler lobHandler) { - this.lobHandler = lobHandler; - } - @Override public void afterPropertiesSet() throws Exception { super.afterPropertiesSet(); @@ -306,7 +293,7 @@ public class JdbcExecutionContextDao extends AbstractJdbcBatchMetadataDao implem getJdbcTemplate().update(getQuery(sql), ps -> { ps.setString(1, shortContext); if (longContext != null) { - lobHandler.getLobCreator().setClobAsString(ps, 2, longContext); + ps.setString(2, longContext); } else { ps.setNull(2, getClobTypeToUse()); @@ -342,7 +329,7 @@ public class JdbcExecutionContextDao extends AbstractJdbcBatchMetadataDao implem } ps.setString(1, shortContext); if (longContext != null) { - lobHandler.getLobCreator().setClobAsString(ps, 2, longContext); + ps.setString(2, longContext); } else { ps.setNull(2, getClobTypeToUse()); diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JdbcJobInstanceDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JdbcJobInstanceDao.java index 27dcc8b7a..8b503899a 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JdbcJobInstanceDao.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JdbcJobInstanceDao.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2025 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. @@ -284,17 +284,6 @@ public class JdbcJobInstanceDao extends AbstractJdbcBatchMetadataDao implements getJdbcTemplate().update(getQuery(DELETE_JOB_INSTANCE), jobInstance.getId()); } - /** - * Setter for {@link DataFieldMaxValueIncrementer} to be used when generating primary - * keys for {@link JobInstance} instances. - * @param jobIncrementer the {@link DataFieldMaxValueIncrementer} - * @deprecated as of v5.0 in favor of using the {@link #setJobInstanceIncrementer} - */ - @Deprecated - public void setJobIncrementer(DataFieldMaxValueIncrementer jobIncrementer) { - this.setJobInstanceIncrementer(jobIncrementer); - } - /** * Setter for {@link DataFieldMaxValueIncrementer} to be used when generating primary * keys for {@link JobInstance} instances. 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 70b0b5443..ac2bd74b6 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-2024 the original author or authors. + * Copyright 2002-2025 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. @@ -56,8 +56,6 @@ import org.springframework.core.convert.support.ConfigurableConversionService; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.support.lob.DefaultLobHandler; -import org.springframework.jdbc.support.lob.LobHandler; import org.springframework.lang.NonNull; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -95,8 +93,6 @@ public class JobRepositoryFactoryBean extends AbstractJobRepositoryFactoryBean i private int maxVarCharLengthForShortContext = AbstractJdbcBatchMetadataDao.DEFAULT_SHORT_CONTEXT_LENGTH; - private LobHandler lobHandler; - private ExecutionContextSerializer serializer; private Integer clobType; @@ -124,19 +120,6 @@ public class JobRepositoryFactoryBean extends AbstractJobRepositoryFactoryBean i this.serializer = serializer; } - /** - * A special handler for large objects. The default is usually fine, except for some - * (usually older) versions of Oracle. The default is determined from the data base - * type. - * @param lobHandler the {@link LobHandler} to set - * @deprecated Since 5.2 with no replacement. Scheduled for removal in v6 - * @see LobHandler - */ - @Deprecated(since = "5.2.0", forRemoval = true) - public void setLobHandler(LobHandler lobHandler) { - this.lobHandler = lobHandler; - } - /** * Public setter for the length of long string columns in database. Do not set this if * you haven't modified the schema. Note this value will be used for the exit message @@ -276,10 +259,6 @@ public class JobRepositoryFactoryBean extends AbstractJobRepositoryFactoryBean i } } - if (lobHandler == null && databaseType.equalsIgnoreCase(DatabaseType.ORACLE.toString())) { - lobHandler = new DefaultLobHandler(); - } - if (serializer == null) { serializer = new DefaultExecutionContextSerializer(); } @@ -355,10 +334,6 @@ public class JobRepositoryFactoryBean extends AbstractJobRepositoryFactoryBean i dao.setSerializer(serializer); dao.setCharset(charset); - if (lobHandler != null) { - dao.setLobHandler(lobHandler); - } - dao.afterPropertiesSet(); dao.setShortContextLength(this.maxVarCharLengthForShortContext); return dao; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java index 55e6a0fdc..3a5eb7ab0 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2024 the original author or authors. + * Copyright 2012-2025 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. @@ -67,8 +67,6 @@ public abstract class AbstractTaskletStepBuilder parent) { @@ -88,7 +86,6 @@ public abstract class AbstractTaskletStepBuilder { - /** - * Initialize a step builder for a step with the given name. - * @param name the name of the step - * @deprecated use {@link StepBuilder#StepBuilder(String, JobRepository)} - */ - @Deprecated(since = "5.0", forRemoval = true) - public StepBuilder(String name) { - super(name); - } - /** * Initialize a step builder for a step with the given name and job repository. * @param name the name of the step @@ -54,17 +44,6 @@ public class StepBuilder extends StepBuilderHelper { super(name, jobRepository); } - /** - * Build a step with a custom tasklet, not necessarily item processing. - * @param tasklet a tasklet - * @return a {@link TaskletStepBuilder} - * @deprecated use {@link StepBuilder#tasklet(Tasklet, PlatformTransactionManager)} - */ - @Deprecated(since = "5.0", forRemoval = true) - public TaskletStepBuilder tasklet(Tasklet tasklet) { - return new TaskletStepBuilder(this).tasklet(tasklet); - } - /** * Build a step with a custom tasklet, not necessarily item processing. * @param tasklet a tasklet @@ -76,27 +55,6 @@ public class StepBuilder extends StepBuilderHelper { return new TaskletStepBuilder(this).tasklet(tasklet, transactionManager); } - /** - * Build a step that processes items in chunks with the size provided. To extend the - * step to being fault tolerant, call the {@link SimpleStepBuilder#faultTolerant()} - * method on the builder. In most cases you will want to parameterize your call to - * this method, to preserve the type safety of your readers and writers, e.g. - * - *

    -	 * new StepBuilder("step1").<Order, Ledger> chunk(100).reader(new OrderReader()).writer(new LedgerWriter())
    -	 * // ... etc.
    -	 * 
    - * @param chunkSize the chunk size (commit interval) - * @return a {@link SimpleStepBuilder} - * @param the type of item to be processed as input - * @param the type of item to be output - * @deprecated use {@link StepBuilder#chunk(int, PlatformTransactionManager)} - */ - @Deprecated(since = "5.0", forRemoval = true) - public SimpleStepBuilder chunk(int chunkSize) { - return new SimpleStepBuilder(this).chunk(chunkSize); - } - /** * Build a step that processes items in chunks with the size provided. To extend the * step to being fault tolerant, call the {@link SimpleStepBuilder#faultTolerant()} @@ -119,29 +77,6 @@ public class StepBuilder extends StepBuilderHelper { return new SimpleStepBuilder(this).transactionManager(transactionManager).chunk(chunkSize); } - /** - * Build a step that processes items in chunks with the completion policy provided. To - * extend the step to being fault tolerant, call the - * {@link SimpleStepBuilder#faultTolerant()} method on the builder. In most cases you - * will want to parameterize your call to this method, to preserve the type safety of - * your readers and writers, e.g. - * - *
    -	 * new StepBuilder("step1").<Order, Ledger> chunk(100).reader(new OrderReader()).writer(new LedgerWriter())
    -	 * // ... etc.
    -	 * 
    - * @param completionPolicy the completion policy to use to control chunk processing - * @return a {@link SimpleStepBuilder} - * @param the type of item to be processed as input - * @param the type of item to be output - * @deprecated use - * {@link StepBuilder#chunk(CompletionPolicy, PlatformTransactionManager)} - */ - @Deprecated(since = "5.0", forRemoval = true) - public SimpleStepBuilder chunk(CompletionPolicy completionPolicy) { - return new SimpleStepBuilder(this).chunk(completionPolicy); - } - /** * Build a step that processes items in chunks with the completion policy provided. To * extend the step to being fault tolerant, call the diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/StepBuilderHelper.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/StepBuilderHelper.java index 577f383e0..802325a30 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/StepBuilderHelper.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/StepBuilderHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2025 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,17 +53,6 @@ public abstract class StepBuilderHelper> { protected final CommonStepProperties properties; - /** - * Create a new {@link StepBuilderHelper}. - * @param name the step name - * @deprecated use {@link StepBuilderHelper#StepBuilderHelper(String, JobRepository)} - */ - @Deprecated(since = "5.1", forRemoval = true) - public StepBuilderHelper(String name) { - this.properties = new CommonStepProperties(); - properties.name = name; - } - /** * Create a new {@link StepBuilderHelper}. * @param name the step name @@ -85,18 +74,6 @@ public abstract class StepBuilderHelper> { this.properties = new CommonStepProperties(parent.properties); } - /** - * Set the job repository - * @param jobRepository the repository to set - * @return this to enable fluent chaining - * @deprecated use {@link StepBuilderHelper#StepBuilderHelper(String, JobRepository)} - */ - @Deprecated(since = "5.1", forRemoval = true) - public B repository(JobRepository jobRepository) { - properties.jobRepository = jobRepository; - return self(); - } - /** * Sets the step observation convention. * @param observationConvention the step observation convention (optional) diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/TaskletStepBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/TaskletStepBuilder.java index bf4aad229..896fce2ce 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/TaskletStepBuilder.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/TaskletStepBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2025 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. @@ -38,18 +38,6 @@ public class TaskletStepBuilder extends AbstractTaskletStepBuilder implements FactoryBean, BeanNameA return taskExecutor; } - /** - * Public setter for the throttle limit. This limits the number of tasks queued for - * concurrent processing to prevent thread pools from being overwhelmed. Defaults to - * {@link TaskExecutorRepeatTemplate#DEFAULT_THROTTLE_LIMIT}. - * @param throttleLimit the throttle limit to set. - * @deprecated since 5.0, scheduled for removal in 6.0. Use a pooled - * {@link TaskExecutor} implementation with a limited capacity of its task queue - * instead. - */ - @Deprecated(since = "5.0", forRemoval = true) - public void setThrottleLimit(int throttleLimit) { - this.throttleLimit = throttleLimit; - } - protected void applyConfiguration(SimpleStepBuilder builder) { builder.reader(itemReader); @@ -482,7 +468,6 @@ public class SimpleStepFactoryBean implements FactoryBean, BeanNameA } builder.transactionManager(transactionManager); builder.transactionAttribute(getTransactionAttribute()); - builder.repository(jobRepository); builder.observationRegistry(observationRegistry); builder.startLimit(startLimit); builder.allowStartIfComplete(allowStartIfComplete); @@ -491,7 +476,6 @@ public class SimpleStepFactoryBean implements FactoryBean, BeanNameA builder.chunkOperations(chunkOperations); builder.stepOperations(stepOperations); builder.taskExecutor(taskExecutor); - builder.throttleLimit(throttleLimit); builder.exceptionHandler(exceptionHandler); if (isReaderTransactionalQueue) { builder.readerIsTransactionalQueue(); diff --git a/spring-batch-core/src/main/resources/org/springframework/batch/core/configuration/xml/spring-batch-5.0.xsd b/spring-batch-core/src/main/resources/org/springframework/batch/core/configuration/xml/spring-batch-5.0.xsd new file mode 100644 index 000000000..1c5b20f37 --- /dev/null +++ b/spring-batch-core/src/main/resources/org/springframework/batch/core/configuration/xml/spring-batch-5.0.xsd @@ -0,0 +1,1368 @@ + + + + + + + + + + + + + + Defines a job composed of a set of steps and + transitions between steps. The job will be exposed in + the enclosing + bean factory as a component of type Job + that can be launched using a + JobLauncher. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Defines a stage in job processing backed by a + Step. The id attribute must be specified since this + step definition + will be referred to from other elements + to form a Job flow. + + + + + + + + + + + + + + + + + Defines a flow composed of a set of steps and + transitions between steps. + + + + + + + + + + + + + + + + + + A reference to a JobExecutionListener (or a POJO + if using before-job-method / after-job-method or + source level + annotations). + + + + + + + + + + + + + + + A bean definition for a step listener (or POJO if + using *-method attributes or source level + annotations) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Defines a stage in job processing backed by a + Step. The id attribute must be specified. The + step + requires either + a chunk definition, + a tasklet reference, or a reference to a + (possibly abstract) parent step. + + + + + + + + + + + + + + + + Declares job should split here into two or more + subflows. + + + + + + + + A subflow within a job, having the same + format as a job, but without a separate identity. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Declares job should include an externalized flow + here. + + + + + + + + + + + + + + + + + + + + + + Declares job should query a decider to determine + where execution should go next. + + + + + + + + + The decider is a reference to a + JobExecutionDecider that can produce a status to base + the next + transition on. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The tasklet is a reference to another bean + definition that implements + the Tasklet interface. + + + + + + + + + + If the tasklet is specified as a bean definition, then a method can be specified and a POJO + will + be adapted to the Tasklet interface. The method suggested should have the same arguments + as Tasklet.execute (or a subset), and have a compatible return type (boolean, void or RepeatStatus). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + An exception class name. + + + + + + + + + + + + + + + + + Classify an exception as "included" in the set. Exceptions of this type or a subclass are + included. + + + + + + + + + + + + + + + + Classify an exception as "excluded" from the + set. Exceptions of this type or a subclass are + excluded + + + + + + + + + + + + + + + A reference to a listener, a POJO with a + listener-annotated method, or a POJO with + a method + referenced by a + *-method attribute. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Defines a transition from this step to the + next + one depending on the value of the exit + status. + + + + + + A pattern to match against the exit status + code. Use * and ? as wildcard characters. When a + step finishes + the most + specific match will be chosen to select the next step. + Hint: + always include a default + transition with on="*". + + + + + + + The name of the step to go to next. Must + resolve to one of the other steps in this job. + + + + + + + + + Declares job should be stop at this point and + provides pointer where execution should continue + when + the job is + restarted. + + + + + + A pattern to match against the exit status + code. Use * and ? as wildcard characters. + When a step + finishes + the most specific match will be chosen to + select the next step. + + + + + + The name of the step to start on when the + stopped job is restarted. + Must resolve to one of the + other steps + in this job. + + + + + + The exit code value to end on, defaults to + STOPPED. + + + + + + + + Declares job should end at this point, without + the possibility of restart. + BatchStatus will be + COMPLETED. + ExitStatus is configurable. + + + + + + A pattern to match against the exit status + code. Use * and ? as wildcard characters. + When a step + finishes + the most specific match will be chosen to + select the next step. + + + + + + The exit code value to end on, defaults to + COMPLETED. + + + + + + + + Declares job should fail at this point. + BatchStatus will be FAILED. ExitStatus is configurable. + + + + + + A pattern to match against the exit status + code. Use * and ? as wildcard characters. + When a step + finishes + the most specific match will be chosen to + select the next step. + + + + + + The exit code value to end on, defaults to + FAILED. + + + + + + + + + + + + + + + + + + + + + + + + + The name of the parent bean from which the + configuration should inherit. + + + + + + + + + + + + + Is this bean "abstract", that is, not meant to be + instantiated itself + but rather just serving as + parent for concrete + child bean definitions? + The default is "false". Specify "true" to + tell the bean factory to not + try + to instantiate that particular bean + in any case. + + Note: This attribute will not be inherited by child + bean definitions. + Hence, it needs to be specified per abstract bean + definition. + + + + + + + + + + Should this list be merged with the corresponding + list provided + by the parent? If not, it will + overwrite the parent + list. + + + + + + + + + + This attribute indicates the method from the + class that should + be used to dynamically create a + proxy. + + + + + + + + + + + + + diff --git a/spring-batch-core/src/main/resources/org/springframework/batch/core/configuration/xml/spring-batch.xsd b/spring-batch-core/src/main/resources/org/springframework/batch/core/configuration/xml/spring-batch.xsd index 1c5b20f37..7656c4585 100644 --- a/spring-batch-core/src/main/resources/org/springframework/batch/core/configuration/xml/spring-batch.xsd +++ b/spring-batch-core/src/main/resources/org/springframework/batch/core/configuration/xml/spring-batch.xsd @@ -6,7 +6,7 @@ xsi:schemaLocation=" http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tool https://www.springframework.org/schema/tool/spring-tool.xsd" - version="5.0"> + version="6.0"> @@ -265,20 +265,6 @@ - - - - - - - - - - - - - - - diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/support/JobRegistryBeanPostProcessorTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/support/JobRegistryBeanPostProcessorTests.java deleted file mode 100644 index a7913ed0b..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/support/JobRegistryBeanPostProcessorTests.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * 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. - * 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.configuration.support; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.Collection; - -import org.junit.jupiter.api.Test; -import org.springframework.batch.core.configuration.DuplicateJobException; -import org.springframework.batch.core.job.JobSupport; -import org.springframework.beans.FatalBeanException; -import org.springframework.context.support.ClassPathXmlApplicationContext; - -/** - * @author Dave Syer - * @author Mahmoud Ben Hassine - * - */ -class JobRegistryBeanPostProcessorTests { - - private final JobRegistryBeanPostProcessor processor = new JobRegistryBeanPostProcessor(); - - @Test - void testInitializationFails() { - Exception exception = assertThrows(IllegalStateException.class, processor::afterPropertiesSet); - assertTrue(exception.getMessage().contains("JobRegistry")); - } - - @Test - void testBeforeInitialization() { - // should be a no-op - assertEquals("foo", processor.postProcessBeforeInitialization("foo", "bar")); - } - - @Test - void testAfterInitializationWithWrongType() { - // should be a no-op - assertEquals("foo", processor.postProcessAfterInitialization("foo", "bar")); - } - - @Test - void testAfterInitializationWithCorrectType() { - MapJobRegistry registry = new MapJobRegistry(); - processor.setJobRegistry(registry); - JobSupport job = new JobSupport(); - job.setBeanName("foo"); - assertNotNull(processor.postProcessAfterInitialization(job, "bar")); - assertEquals("[foo]", registry.getJobNames().toString()); - } - - @Test - void testAfterInitializationWithGroupName() { - MapJobRegistry registry = new MapJobRegistry(); - processor.setJobRegistry(registry); - processor.setGroupName("jobs"); - JobSupport job = new JobSupport(); - job.setBeanName("foo"); - assertNotNull(processor.postProcessAfterInitialization(job, "bar")); - assertEquals("[jobs.foo]", registry.getJobNames().toString()); - } - - @Test - void testAfterInitializationWithDuplicate() { - MapJobRegistry registry = new MapJobRegistry(); - processor.setJobRegistry(registry); - JobSupport job = new JobSupport(); - job.setBeanName("foo"); - processor.postProcessAfterInitialization(job, "bar"); - Exception exception = assertThrows(FatalBeanException.class, - () -> processor.postProcessAfterInitialization(job, "spam")); - assertTrue(exception.getCause() instanceof DuplicateJobException); - } - - @Test - void testUnregisterOnDestroy() throws Exception { - MapJobRegistry registry = new MapJobRegistry(); - processor.setJobRegistry(registry); - JobSupport job = new JobSupport(); - job.setBeanName("foo"); - assertNotNull(processor.postProcessAfterInitialization(job, "bar")); - processor.destroy(); - assertEquals("[]", registry.getJobNames().toString()); - } - - @Test - void testExecutionWithApplicationContext() throws Exception { - ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("test-context.xml", getClass()); - MapJobRegistry registry = (MapJobRegistry) context.getBean("registry"); - Collection configurations = registry.getJobNames(); - String[] names = context.getBeanNamesForType(JobSupport.class); - int count = names.length; - // Each concrete bean of type JobConfiguration is registered... - assertEquals(count, configurations.size()); - // N.B. there is a failure / wonky mode where a parent bean is given an - // explicit name or beanName (using property setter): in this case then - // child beans will have the same name and will be re-registered (and - // override, if the registry supports that). - assertNotNull(registry.getJob("test-job")); - assertEquals(context.getBean("test-job-with-name"), registry.getJob("foo")); - assertEquals(context.getBean("test-job-with-bean-name"), registry.getJob("bar")); - assertEquals(context.getBean("test-job-with-parent-and-name"), registry.getJob("spam")); - assertEquals(context.getBean("test-job-with-parent-and-bean-name"), registry.getJob("bucket")); - assertEquals(context.getBean("test-job-with-concrete-parent"), registry.getJob("maps")); - assertEquals(context.getBean("test-job-with-concrete-parent-and-name"), registry.getJob("oof")); - assertEquals(context.getBean("test-job-with-concrete-parent-and-bean-name"), registry.getJob("rab")); - } - -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/StepParserStepFactoryBeanTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/StepParserStepFactoryBeanTests.java index 37949ce5f..91f4963ea 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/StepParserStepFactoryBeanTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/StepParserStepFactoryBeanTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2025 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. @@ -239,7 +239,6 @@ class StepParserStepFactoryBeanTests { fb.setIsReaderTransactionalQueue(true); fb.setRetryLimit(5); fb.setSkipLimit(100); - fb.setThrottleLimit(10); fb.setRetryListeners(new RetryListener() { }); @SuppressWarnings("unchecked") @@ -251,7 +250,7 @@ class StepParserStepFactoryBeanTests { assertTrue(step instanceof TaskletStep); Object throttleLimit = ReflectionTestUtils.getField(ReflectionTestUtils.getField(step, "stepOperations"), "throttleLimit"); - assertEquals(10, throttleLimit); + assertEquals(4, throttleLimit); Object tasklet = ReflectionTestUtils.getField(step, "tasklet"); assertTrue(tasklet instanceof ChunkOrientedTasklet); assertFalse((Boolean) ReflectionTestUtils.getField(tasklet, "buffering")); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/StepParserTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/StepParserTests.java index 541e40226..7d709d6ef 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/StepParserTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/StepParserTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2025 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. @@ -88,8 +88,6 @@ public class StepParserTests { StepParserStepFactoryBean factory = beans.get(factoryName); TaskletStep bean = (TaskletStep) factory.getObject(); assertEquals(25, bean.getStartLimit(), "wrong start-limit:"); - Object throttleLimit = ReflectionTestUtils.getField(factory, "throttleLimit"); - assertEquals(10, throttleLimit); } @Test diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/JobRepositoryFactoryBeanTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/JobRepositoryFactoryBeanTests.java index 806a30e5c..a8669c4c3 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/JobRepositoryFactoryBeanTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/JobRepositoryFactoryBeanTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2025 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. @@ -42,8 +42,6 @@ import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer; -import org.springframework.jdbc.support.lob.DefaultLobHandler; -import org.springframework.jdbc.support.lob.LobHandler; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.Isolation; @@ -112,48 +110,6 @@ class JobRepositoryFactoryBeanTests { } - @Test - void testOracleLobHandler() throws Exception { - - factory.setDatabaseType("ORACLE"); - - incrementerFactory = mock(); - when(incrementerFactory.isSupportedIncrementerType("ORACLE")).thenReturn(true); - when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_SEQ")).thenReturn(new StubIncrementer()); - when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_EXECUTION_SEQ")) - .thenReturn(new StubIncrementer()); - when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "STEP_EXECUTION_SEQ")) - .thenReturn(new StubIncrementer()); - factory.setIncrementerFactory(incrementerFactory); - - factory.afterPropertiesSet(); - LobHandler lobHandler = (LobHandler) ReflectionTestUtils.getField(factory, "lobHandler"); - assertTrue(lobHandler instanceof DefaultLobHandler); - - } - - @Test - void testCustomLobHandler() throws Exception { - - factory.setDatabaseType("ORACLE"); - - incrementerFactory = mock(); - when(incrementerFactory.isSupportedIncrementerType("ORACLE")).thenReturn(true); - when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_SEQ")).thenReturn(new StubIncrementer()); - when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_EXECUTION_SEQ")) - .thenReturn(new StubIncrementer()); - when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "STEP_EXECUTION_SEQ")) - .thenReturn(new StubIncrementer()); - factory.setIncrementerFactory(incrementerFactory); - - LobHandler lobHandler = new DefaultLobHandler(); - factory.setLobHandler(lobHandler); - - factory.afterPropertiesSet(); - assertEquals(lobHandler, ReflectionTestUtils.getField(factory, "lobHandler")); - - } - @Test @SuppressWarnings("unchecked") void tesDefaultSerializer() throws Exception { diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/builder/StepBuilderTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/builder/StepBuilderTests.java index b3e1114d6..61804ee1d 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/builder/StepBuilderTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/builder/StepBuilderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2025 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. @@ -252,11 +252,6 @@ class StepBuilderTests { testReturnedTypeOfSetterIsAssignableToSimpleStepBuilder(builder -> builder.taskExecutor(null)); } - @Test - void testReturnedTypeOfThrottleLimitIsAssignableToSimpleStepBuilder() throws Exception { - testReturnedTypeOfSetterIsAssignableToSimpleStepBuilder(builder -> builder.throttleLimit(4)); - } - @Test void testReturnedTypeOfExceptionHandlerIsAssignableToSimpleStepBuilder() throws Exception { testReturnedTypeOfSetterIsAssignableToSimpleStepBuilder( diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SimpleStepFactoryBeanTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SimpleStepFactoryBeanTests.java index d4f6137db..445575679 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SimpleStepFactoryBeanTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SimpleStepFactoryBeanTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2024 the original author or authors. + * Copyright 2006-2025 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. @@ -151,7 +151,6 @@ class SimpleStepFactoryBeanTests { SimpleStepFactoryBean factory = getStepFactory("foo", "bar"); factory.setTaskExecutor(new SimpleAsyncTaskExecutor()); - factory.setThrottleLimit(1); AbstractStep step = (AbstractStep) factory.getObject(); step.setName("step1"); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/AsyncChunkOrientedStepIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/AsyncChunkOrientedStepIntegrationTests.java index 5a3efbf65..323c89cd0 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/AsyncChunkOrientedStepIntegrationTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/AsyncChunkOrientedStepIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2025 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. @@ -109,7 +109,6 @@ class AsyncChunkOrientedStepIntegrationTests { job = new JobSupport("FOO"); TaskExecutorRepeatTemplate repeatTemplate = new TaskExecutorRepeatTemplate(); - repeatTemplate.setThrottleLimit(2); repeatTemplate.setTaskExecutor(new SimpleAsyncTaskExecutor()); step.setStepOperations(repeatTemplate); step.setTransactionManager(transactionManager); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/AsyncTaskletStepTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/AsyncTaskletStepTests.java index 5062972d0..7002c5275 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/AsyncTaskletStepTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/AsyncTaskletStepTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2025 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. @@ -90,7 +90,6 @@ class AsyncTaskletStepTests { step.setJobRepository(jobRepository); TaskExecutorRepeatTemplate template = new TaskExecutorRepeatTemplate(); - template.setThrottleLimit(throttleLimit); SimpleAsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor(); taskExecutor.setConcurrencyLimit(concurrencyLimit); template.setTaskExecutor(taskExecutor); diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/support/JobRegistryIntegrationTests-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/support/JobRegistryIntegrationTests-context.xml index 0537f4173..dccc63e23 100644 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/support/JobRegistryIntegrationTests-context.xml +++ b/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/support/JobRegistryIntegrationTests-context.xml @@ -13,7 +13,7 @@ - + diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/support/test-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/support/test-context.xml index 95b739c01..1835e8294 100644 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/support/test-context.xml +++ b/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/support/test-context.xml @@ -10,7 +10,7 @@ http://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx.xsd"> + class="org.springframework.batch.core.configuration.support.JobRegistrySmartInitializingSingleton"> diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/support/trivial-context-autoregister.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/support/trivial-context-autoregister.xml index cce014e57..e01d220d0 100644 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/support/trivial-context-autoregister.xml +++ b/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/support/trivial-context-autoregister.xml @@ -11,7 +11,7 @@ - + diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/JobRegistryJobParserTests-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/JobRegistryJobParserTests-context.xml index ecbf6bbf3..240e5baa2 100644 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/JobRegistryJobParserTests-context.xml +++ b/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/JobRegistryJobParserTests-context.xml @@ -20,7 +20,7 @@ + class="org.springframework.batch.core.configuration.support.JobRegistrySmartInitializingSingleton"> diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/JobRepositoryParserTests-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/JobRepositoryParserTests-context.xml index e7993737b..ae15fc673 100644 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/JobRepositoryParserTests-context.xml +++ b/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/JobRepositoryParserTests-context.xml @@ -14,9 +14,8 @@ - - + \ No newline at end of file diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/StepParserTaskletAttributesTests-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/StepParserTaskletAttributesTests-context.xml index 48f6ddedd..68b7a04fe 100644 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/StepParserTaskletAttributesTests-context.xml +++ b/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/StepParserTaskletAttributesTests-context.xml @@ -9,7 +9,7 @@ - + diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/TaskletStepAllowStartIfCompleteTests-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/TaskletStepAllowStartIfCompleteTests-context.xml index 8620593d3..c122971d1 100644 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/TaskletStepAllowStartIfCompleteTests-context.xml +++ b/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/TaskletStepAllowStartIfCompleteTests-context.xml @@ -38,7 +38,7 @@ - + diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/launch/support/launcher-with-locator.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/launch/support/launcher-with-locator.xml index 39f42d9ad..5cb22aea1 100644 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/launch/support/launcher-with-locator.xml +++ b/spring-batch-core/src/test/resources/org/springframework/batch/core/launch/support/launcher-with-locator.xml @@ -15,7 +15,7 @@ - + diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/launch/support/test-environment-with-registry-and-auto-register.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/launch/support/test-environment-with-registry-and-auto-register.xml index eac8d8e9f..6045e96ae 100644 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/launch/support/test-environment-with-registry-and-auto-register.xml +++ b/spring-batch-core/src/test/resources/org/springframework/batch/core/launch/support/test-environment-with-registry-and-auto-register.xml @@ -9,7 +9,7 @@ - + diff --git a/spring-batch-core/src/test/resources/simple-job-launcher-context.xml b/spring-batch-core/src/test/resources/simple-job-launcher-context.xml index 4e9986d0f..1dbd4308a 100644 --- a/spring-batch-core/src/test/resources/simple-job-launcher-context.xml +++ b/spring-batch-core/src/test/resources/simple-job-launcher-context.xml @@ -11,7 +11,7 @@ - + diff --git a/spring-batch-docs/modules/ROOT/pages/appendix.adoc b/spring-batch-docs/modules/ROOT/pages/appendix.adoc index 28d4ca344..cbbb93e55 100644 --- a/spring-batch-docs/modules/ROOT/pages/appendix.adoc +++ b/spring-batch-docs/modules/ROOT/pages/appendix.adoc @@ -52,11 +52,10 @@ This reader stores message offsets in the execution context to support restart c rows, such that large datasets can be read without running out of memory.|Yes |`ListItemReader`|Provides the items from a list, one at a time.|No -|`MongoItemReader`|Given a `MongoOperations` object and a JSON-based MongoDB +|`MongoPagingItemReader`|Given a `MongoOperations` object and a JSON-based MongoDB query, provides items received from the `MongoOperations#find()` method.|Yes -|`Neo4jItemReader`|Given a `Neo4jOperations` object and the components of a - Cyhper query, items are returned as the result of the Neo4jOperations.query - method.|Yes +|`MongoCursorItemReader`|Given a `MongoOperations` object and a JSON-based MongoDB + query, provides items received from the `MongoOperations#stream()` method.|Yes |`RepositoryItemReader`|Given a Spring Data `PagingAndSortingRepository` object, a `Sort`, and the name of method to execute, returns items provided by the Spring Data repository implementation.|Yes @@ -106,9 +105,6 @@ This reader stores message offsets in the execution context to support restart c |`MongoItemWriter`|Given a `MongoOperations` object, items are written through the `MongoOperations.save(Object)` method. The actual write is delayed until the last possible moment before the transaction commits.|Yes -|`Neo4jItemWriter`|Given a `Neo4jOperations` object, items are persisted through the - `save(Object)` method or deleted through the `delete(Object)`, as dictated by the - `ItemWriter's` configuration|Yes |`PropertyExtractingDelegatingItemWriter`|Extends `AbstractMethodInvokingDelegator` creating arguments on the fly. Arguments are created by retrieving the values from the fields in the item to be processed (through a diff --git a/spring-batch-docs/modules/ROOT/pages/job/advanced-meta-data.adoc b/spring-batch-docs/modules/ROOT/pages/job/advanced-meta-data.adoc index bfa7ff3d1..4102a8460 100644 --- a/spring-batch-docs/modules/ROOT/pages/job/advanced-meta-data.adoc +++ b/spring-batch-docs/modules/ROOT/pages/job/advanced-meta-data.adoc @@ -177,58 +177,6 @@ You can populate a `JobRegistry` in one of the following ways: by using a bean post processor, or by using a smart initializing singleton or by using a registrar lifecycle component. The coming sections describe these mechanisms. -[[jobregistrybeanpostprocessor]] -=== JobRegistryBeanPostProcessor - -This is a bean post-processor that can register all jobs as they are created. - -[tabs] -==== -Java:: -+ -The following example shows how to include the `JobRegistryBeanPostProcessor` for a job -defined in Java: -+ -.Java Configuration -[source, java] ----- -@Bean -public JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor(JobRegistry jobRegistry) { - JobRegistryBeanPostProcessor postProcessor = new JobRegistryBeanPostProcessor(); - postProcessor.setJobRegistry(jobRegistry); - return postProcessor; -} ----- - -XML:: -+ -The following example shows how to include the `JobRegistryBeanPostProcessor` for a job -defined in XML: -+ -.XML Configuration -[source, xml] ----- - - - ----- - -==== - - - -Although it is not strictly necessary, the post-processor in the -example has been given an `id` so that it can be included in child -contexts (for example, as a parent bean definition) and cause all jobs created -there to also be registered automatically. - -[WARNING] -.Deprecation -==== -As of version 5.2, the `JobRegistryBeanPostProcessor` class is deprecated in favor of -`JobRegistrySmartInitializingSingleton`, see xref:#jobregistrysmartinitializingsingleton[JobRegistrySmartInitializingSingleton]. -==== - [[jobregistrysmartinitializingsingleton]] === JobRegistrySmartInitializingSingleton @@ -343,7 +291,7 @@ configuration in the child, provided it should be the same as the parent. You can use `AutomaticJobRegistrar` in -conjunction with a `JobRegistryBeanPostProcessor` +conjunction with a `JobRegistrySmartInitializingSingleton` (as long as you also use `DefaultJobLoader`). For instance, this might be desirable if there are jobs defined in the main parent context as well as in the child diff --git a/spring-batch-docs/modules/ROOT/pages/readers-and-writers/item-reader-writer-implementations.adoc b/spring-batch-docs/modules/ROOT/pages/readers-and-writers/item-reader-writer-implementations.adoc index 628b2b85b..4f3e16592 100644 --- a/spring-batch-docs/modules/ROOT/pages/readers-and-writers/item-reader-writer-implementations.adoc +++ b/spring-batch-docs/modules/ROOT/pages/readers-and-writers/item-reader-writer-implementations.adoc @@ -161,21 +161,21 @@ construct an instance of the `KafkaItemWriter`. == Database Readers Spring Batch offers the following database readers: -* xref:readers-and-writers/item-reader-writer-implementations.adoc#Neo4jItemReader[`Neo4jItemReader`] -* xref:readers-and-writers/item-reader-writer-implementations.adoc#mongoItemReader[`MongoItemReader`] +* xref:readers-and-writers/item-reader-writer-implementations.adoc#mongoPagingItemReader[`MongoPagingItemReader`] +* xref:readers-and-writers/item-reader-writer-implementations.adoc#mongoCursorItemReader[`MongoCursorItemReader`] * xref:readers-and-writers/item-reader-writer-implementations.adoc#repositoryItemReader[`RepositoryItemReader`] -[[Neo4jItemReader]] -=== `Neo4jItemReader` -The `Neo4jItemReader` is an `ItemReader` that reads objects from the graph database Neo4j -by using a paging technique. Spring Batch provides a `Neo4jItemReaderBuilder` to -construct an instance of the `Neo4jItemReader`. +[[mongoPagingItemReader]] +=== `MongoPagingItemReader` +The `MongoPagingItemReader` is an `ItemReader` that reads documents from MongoDB by using a +paging technique. Spring Batch provides a `MongoPagingItemReaderBuilder` to construct an +instance of the `MongoPagingItemReader`. -[[mongoItemReader]] -=== `MongoItemReader` -The `MongoItemReader` is an `ItemReader` that reads documents from MongoDB by using a -paging technique. Spring Batch provides a `MongoItemReaderBuilder` to construct an -instance of the `MongoItemReader`. +[[mongoCursorItemReader]] +=== `MongoCursorItemReader` +The `MongoCursorItemReader` is an `ItemReader` that reads documents from MongoDB by using a +streaming technique. Spring Batch provides a `MongoCursorItemReaderBuilder` to construct an +instance of the `MongoCursorItemReader`. [[repositoryItemReader]] === `RepositoryItemReader` @@ -187,18 +187,11 @@ construct an instance of the `RepositoryItemReader`. == Database Writers Spring Batch offers the following database writers: -* xref:readers-and-writers/item-reader-writer-implementations.adoc#neo4jItemWriter[`Neo4jItemWriter`] * xref:readers-and-writers/item-reader-writer-implementations.adoc#mongoItemWriter[`MongoItemWriter`] * xref:readers-and-writers/item-reader-writer-implementations.adoc#repositoryItemWriter[`RepositoryItemWriter`] * xref:readers-and-writers/item-reader-writer-implementations.adoc#jdbcBatchItemWriter[`JdbcBatchItemWriter`] * xref:readers-and-writers/item-reader-writer-implementations.adoc#jpaItemWriter[`JpaItemWriter`] -[[neo4jItemWriter]] -=== `Neo4jItemWriter` -The `Neo4jItemWriter` is an `ItemWriter` implementation that writes to a Neo4j database. -Spring Batch provides a `Neo4jItemWriterBuilder` to construct an instance of the -`Neo4jItemWriter`. - [[mongoItemWriter]] === `MongoItemWriter` The `MongoItemWriter` is an `ItemWriter` implementation that writes to a MongoDB store diff --git a/spring-batch-docs/modules/ROOT/pages/scalability.adoc b/spring-batch-docs/modules/ROOT/pages/scalability.adoc index b00353c4e..48f711e6b 100644 --- a/spring-batch-docs/modules/ROOT/pages/scalability.adoc +++ b/spring-batch-docs/modules/ROOT/pages/scalability.adoc @@ -133,29 +133,6 @@ Note also that there may be limits placed on concurrency by any pooled resources your step, such as a `DataSource`. Be sure to make the pool in those resources at least as large as the desired number of concurrent threads in the step. -[WARNING] -.Throttle limit deprecation -==== -As of v5.0, the throttle limit is deprecated with no replacement. If you want to replace the -current throttling mechanism in the default `TaskExecutorRepeatTemplate`, you need to provide -a custom `RepeatOperations` implementation (based on a `TaskExecutor` with a bounded task queue) -and set it on the step with `StepBuilder#stepOperations`: - -.Java Configuration -[source, java] ----- -@Bean -public Step sampleStep(RepeatOperations customRepeatOperations, JobRepository jobRepository, PlatformTransactionManager transactionManager) { - return new StepBuilder("sampleStep", jobRepository) - .chunk(10, transactionManager) - .reader(itemReader()) - .writer(itemWriter()) - .stepOperations(customRepeatOperations) - .build(); -} ----- -==== - There are some practical limitations of using multi-threaded `Step` implementations for some common batch use cases. Many participants in a `Step` (such as readers and writers) are stateful. If the state is not segregated by thread, those components are not diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoItemReader.java deleted file mode 100644 index 9c8ce109d..000000000 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoItemReader.java +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright 2012-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.item.data; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.bson.Document; -import org.bson.codecs.DecoderContext; - -import org.springframework.batch.item.ExecutionContext; -import org.springframework.batch.item.ItemReader; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.mongodb.core.MongoOperations; -import org.springframework.data.mongodb.core.query.BasicQuery; -import org.springframework.data.mongodb.core.query.Query; -import org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec; -import org.springframework.data.mongodb.util.json.ParameterBindingJsonReader; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.StringUtils; - -/** - *

    - * Restartable {@link ItemReader} that reads documents from MongoDB via a paging - * technique. - *

    - * - *

    - * If you set JSON String query {@link #setQuery(String)} then it executes the JSON to - * retrieve the requested documents. - *

    - * - *

    - * If you set Query object {@link #setQuery(Query)} then it executes the Query to retrieve - * the requested documents. - *

    - * - *

    - * The query is executed using paged requests specified in the {@link #setPageSize(int)}. - * Additional pages are requested as needed to provide data when the {@link #read()} - * method is called. - *

    - * - *

    - * The JSON String query provided supports parameter substitution via ?<index> - * placeholders where the <index> indicates the index of the parameterValue to - * substitute. - *

    - * - *

    - * The implementation is thread-safe between calls to {@link #open(ExecutionContext)}, but - * remember to use saveState=false if used in a multi-threaded client (no - * restart available). - *

    - * - * @author Michael Minella - * @author Takaaki Iida - * @author Mahmoud Ben Hassine - * @author Parikshit Dutta - * @deprecated Use {@link MongoPagingItemReader} instead. Scheduled for removal in v5.3 or - * later. - */ -@Deprecated(since = "5.1", forRemoval = true) -public class MongoItemReader extends AbstractPaginatedDataItemReader implements InitializingBean { - - protected MongoOperations template; - - protected Query query; - - protected String queryString; - - protected Class type; - - protected Sort sort; - - protected String hint; - - protected String fields; - - protected String collection; - - protected List parameterValues = new ArrayList<>(); - - public MongoItemReader() { - super(); - setName(ClassUtils.getShortName(MongoItemReader.class)); - } - - /** - * A Mongo Query to be used. - * @param query Mongo Query to be used. - */ - public void setQuery(Query query) { - this.query = query; - } - - /** - * Used to perform operations against the MongoDB instance. Also handles the mapping - * of documents to objects. - * @param template the MongoOperations instance to use - * @see MongoOperations - */ - public void setTemplate(MongoOperations template) { - this.template = template; - } - - /** - * A JSON formatted MongoDB query. Parameterization of the provided query is allowed - * via ?<index> placeholders where the <index> indicates the index of the - * parameterValue to substitute. - * @param queryString JSON formatted Mongo query - */ - public void setQuery(String queryString) { - this.queryString = queryString; - } - - /** - * The type of object to be returned for each {@link #read()} call. - * @param type the type of object to return - */ - public void setTargetType(Class type) { - this.type = type; - } - - /** - * {@link List} of values to be substituted in for each of the parameters in the - * query. - * @param parameterValues values - */ - public void setParameterValues(List parameterValues) { - Assert.notNull(parameterValues, "Parameter values must not be null"); - this.parameterValues = parameterValues; - } - - /** - * JSON defining the fields to be returned from the matching documents by MongoDB. - * @param fields JSON string that identifies the fields to sort by. - */ - public void setFields(String fields) { - this.fields = fields; - } - - /** - * {@link Map} of property - * names/{@link org.springframework.data.domain.Sort.Direction} values to sort the - * input by. - * @param sorts map of properties and direction to sort each. - */ - public void setSort(Map sorts) { - Assert.notNull(sorts, "Sorts must not be null"); - this.sort = convertToSort(sorts); - } - - /** - * @param collection Mongo collection to be queried. - */ - public void setCollection(String collection) { - this.collection = collection; - } - - /** - * JSON String telling MongoDB what index to use. - * @param hint string indicating what index to use. - */ - public void setHint(String hint) { - this.hint = hint; - } - - @Override - @SuppressWarnings("unchecked") - protected Iterator doPageRead() { - if (queryString != null) { - Pageable pageRequest = PageRequest.of(page, pageSize, sort); - - String populatedQuery = replacePlaceholders(queryString, parameterValues); - - Query mongoQuery; - - if (StringUtils.hasText(fields)) { - mongoQuery = new BasicQuery(populatedQuery, fields); - } - else { - mongoQuery = new BasicQuery(populatedQuery); - } - - mongoQuery.with(pageRequest); - - if (StringUtils.hasText(hint)) { - mongoQuery.withHint(hint); - } - - if (StringUtils.hasText(collection)) { - return (Iterator) template.find(mongoQuery, type, collection).iterator(); - } - else { - return (Iterator) template.find(mongoQuery, type).iterator(); - } - - } - else { - Pageable pageRequest = PageRequest.of(page, pageSize); - query.with(pageRequest); - - if (StringUtils.hasText(collection)) { - return (Iterator) template.find(query, type, collection).iterator(); - } - else { - return (Iterator) template.find(query, type).iterator(); - } - } - } - - /** - * Checks mandatory properties - * - * @see InitializingBean#afterPropertiesSet() - */ - @Override - public void afterPropertiesSet() throws Exception { - Assert.state(template != null, "An implementation of MongoOperations is required."); - Assert.state(type != null, "A type to convert the input into is required."); - Assert.state(queryString != null || query != null, "A query is required."); - - if (queryString != null) { - Assert.state(sort != null, "A sort is required."); - } - } - - protected String replacePlaceholders(String input, List values) { - ParameterBindingJsonReader reader = new ParameterBindingJsonReader(input, values.toArray()); - DecoderContext decoderContext = DecoderContext.builder().build(); - Document document = new ParameterBindingDocumentCodec().decode(reader, decoderContext); - return document.toJson(); - } - - protected Sort convertToSort(Map sorts) { - List sortValues = new ArrayList<>(sorts.size()); - - for (Map.Entry curSort : sorts.entrySet()) { - sortValues.add(new Sort.Order(curSort.getValue(), curSort.getKey())); - } - - return Sort.by(sortValues); - } - -} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoItemWriter.java index b7aa27f37..6e8219512 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoItemWriter.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoItemWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2024 the original author or authors. + * Copyright 2012-2025 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. @@ -97,19 +97,6 @@ public class MongoItemWriter implements ItemWriter, InitializingBean { this.bufferKey = new Object(); } - /** - * Indicates if the items being passed to the writer are to be saved or removed from - * the data store. If set to false (default), the items will be saved or update using - * {@link Mode#UPSERT}. If set to true, then items will be removed. - * @param delete removal indicator - * @deprecated use {@link MongoItemWriter#setMode(Mode)} instead. Scheduled for - * removal in v5.3 or later. - */ - @Deprecated(since = "5.1", forRemoval = true) - public void setDelete(boolean delete) { - this.mode = (delete) ? Mode.REMOVE : Mode.UPSERT; - } - /** * Set the operating {@link Mode} to be applied by this writer. Defaults to * {@link Mode#UPSERT}. diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoPagingItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoPagingItemReader.java index 5c2278cac..e9e8ff83d 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoPagingItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoPagingItemReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2024 the original author or authors. + * Copyright 2012-2025 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,16 +15,27 @@ */ package org.springframework.batch.item.data; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; +import org.bson.Document; +import org.bson.codecs.DecoderContext; import org.springframework.batch.item.ExecutionContext; import org.springframework.batch.item.ItemReader; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.data.mongodb.core.query.BasicQuery; import org.springframework.data.mongodb.core.query.Query; +import org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec; +import org.springframework.data.mongodb.util.json.ParameterBindingJsonReader; +import org.springframework.util.Assert; import org.springframework.util.ClassUtils; +import org.springframework.util.StringUtils; /** *

    @@ -67,78 +78,186 @@ import org.springframework.util.ClassUtils; * @author Mahmoud Ben Hassine * @author Parikshit Dutta */ -public class MongoPagingItemReader extends MongoItemReader { +public class MongoPagingItemReader extends AbstractPaginatedDataItemReader implements InitializingBean { + + protected MongoOperations template; + + protected Query query; + + protected String queryString; + + protected Class type; + + protected Sort sort; + + protected String hint; + + protected String fields; + + protected String collection; + + protected List parameterValues = new ArrayList<>(); - /** - * Create a new {@link MongoPagingItemReader}. - */ public MongoPagingItemReader() { + super(); setName(ClassUtils.getShortName(MongoPagingItemReader.class)); } - @Override - public void setTemplate(MongoOperations template) { - super.setTemplate(template); - } - - @Override + /** + * A Mongo Query to be used. + * @param query Mongo Query to be used. + */ public void setQuery(Query query) { - super.setQuery(query); + this.query = query; } - @Override + /** + * Used to perform operations against the MongoDB instance. Also handles the mapping + * of documents to objects. + * @param template the MongoOperations instance to use + * @see MongoOperations + */ + public void setTemplate(MongoOperations template) { + this.template = template; + } + + /** + * A JSON formatted MongoDB query. Parameterization of the provided query is allowed + * via ?<index> placeholders where the <index> indicates the index of the + * parameterValue to substitute. + * @param queryString JSON formatted Mongo query + */ public void setQuery(String queryString) { - super.setQuery(queryString); + this.queryString = queryString; } - @Override + /** + * The type of object to be returned for each {@link #read()} call. + * @param type the type of object to return + */ public void setTargetType(Class type) { - super.setTargetType(type); + this.type = type; } - @Override + /** + * {@link List} of values to be substituted in for each of the parameters in the + * query. + * @param parameterValues values + */ public void setParameterValues(List parameterValues) { - super.setParameterValues(parameterValues); + Assert.notNull(parameterValues, "Parameter values must not be null"); + this.parameterValues = parameterValues; } - @Override + /** + * JSON defining the fields to be returned from the matching documents by MongoDB. + * @param fields JSON string that identifies the fields to sort by. + */ public void setFields(String fields) { - super.setFields(fields); + this.fields = fields; } - @Override + /** + * {@link Map} of property + * names/{@link org.springframework.data.domain.Sort.Direction} values to sort the + * input by. + * @param sorts map of properties and direction to sort each. + */ public void setSort(Map sorts) { - super.setSort(sorts); + Assert.notNull(sorts, "Sorts must not be null"); + this.sort = convertToSort(sorts); } - @Override + /** + * @param collection Mongo collection to be queried. + */ public void setCollection(String collection) { - super.setCollection(collection); + this.collection = collection; + } + + /** + * JSON String telling MongoDB what index to use. + * @param hint string indicating what index to use. + */ + public void setHint(String hint) { + this.hint = hint; } @Override - public void setHint(String hint) { - super.setHint(hint); + @SuppressWarnings("unchecked") + protected Iterator doPageRead() { + if (queryString != null) { + Pageable pageRequest = PageRequest.of(page, pageSize, sort); + + String populatedQuery = replacePlaceholders(queryString, parameterValues); + + Query mongoQuery; + + if (StringUtils.hasText(fields)) { + mongoQuery = new BasicQuery(populatedQuery, fields); + } + else { + mongoQuery = new BasicQuery(populatedQuery); + } + + mongoQuery.with(pageRequest); + + if (StringUtils.hasText(hint)) { + mongoQuery.withHint(hint); + } + + if (StringUtils.hasText(collection)) { + return (Iterator) template.find(mongoQuery, type, collection).iterator(); + } + else { + return (Iterator) template.find(mongoQuery, type).iterator(); + } + + } + else { + Pageable pageRequest = PageRequest.of(page, pageSize); + query.with(pageRequest); + + if (StringUtils.hasText(collection)) { + return (Iterator) template.find(query, type, collection).iterator(); + } + else { + return (Iterator) template.find(query, type).iterator(); + } + } } + /** + * Checks mandatory properties + * + * @see InitializingBean#afterPropertiesSet() + */ @Override public void afterPropertiesSet() throws Exception { - super.afterPropertiesSet(); + Assert.state(template != null, "An implementation of MongoOperations is required."); + Assert.state(type != null, "A type to convert the input into is required."); + Assert.state(queryString != null || query != null, "A query is required."); + + if (queryString != null) { + Assert.state(sort != null, "A sort is required."); + } } - @Override - protected Iterator doPageRead() { - return super.doPageRead(); - } - - @Override protected String replacePlaceholders(String input, List values) { - return super.replacePlaceholders(input, values); + ParameterBindingJsonReader reader = new ParameterBindingJsonReader(input, values.toArray()); + DecoderContext decoderContext = DecoderContext.builder().build(); + Document document = new ParameterBindingDocumentCodec().decode(reader, decoderContext); + return document.toJson(); } - @Override protected Sort convertToSort(Map sorts) { - return super.convertToSort(sorts); + List sortValues = new ArrayList<>(sorts.size()); + + for (Map.Entry curSort : sorts.entrySet()) { + sortValues.add(new Sort.Order(curSort.getValue(), curSort.getKey())); + } + + return Sort.by(sortValues); } -} +} \ No newline at end of file diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/Neo4jItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/Neo4jItemReader.java deleted file mode 100644 index 07daeaa9d..000000000 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/Neo4jItemReader.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright 2012-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.item.data; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.neo4j.ogm.session.Session; -import org.neo4j.ogm.session.SessionFactory; - -import org.springframework.batch.item.ItemReader; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - *

    - * Restartable {@link ItemReader} that reads objects from the graph database Neo4j via a - * paging technique. - *

    - * - *

    - * It executes cypher queries built from the statement fragments provided to retrieve the - * requested data. The query is executed using paged requests of a size specified in - * {@link #setPageSize(int)}. Additional pages are requested as needed when the - * {@link #read()} method is called. On restart, the reader will begin again at the same - * number item it left off at. - *

    - * - *

    - * Performance is dependent on your Neo4J configuration (embedded or remote) as well as - * page size. Setting a fairly large page size and using a commit interval that matches - * the page size should provide better performance. - *

    - * - *

    - * This implementation is thread-safe between calls to - * {@link #open(org.springframework.batch.item.ExecutionContext)}, however you should set - * saveState=false if used in a multi-threaded environment (no restart - * available). - *

    - * - * @author Michael Minella - * @author Mahmoud Ben Hassine - * @deprecated since 5.0 in favor of the item reader from ... - */ -@Deprecated -public class Neo4jItemReader extends AbstractPaginatedDataItemReader implements InitializingBean { - - protected Log logger = LogFactory.getLog(getClass()); - - private SessionFactory sessionFactory; - - private String startStatement; - - private String returnStatement; - - private String matchStatement; - - private String whereStatement; - - private String orderByStatement; - - private Class targetType; - - private Map parameterValues; - - /** - * Optional parameters to be used in the cypher query. - * @param parameterValues the parameter values to be used in the cypher query - */ - public void setParameterValues(Map parameterValues) { - this.parameterValues = parameterValues; - } - - protected final Map getParameterValues() { - return this.parameterValues; - } - - /** - * The start segment of the cypher query. START is prepended to the statement provided - * and should not be included. - * @param startStatement the start fragment of the cypher query. - */ - public void setStartStatement(String startStatement) { - this.startStatement = startStatement; - } - - /** - * The return statement of the cypher query. RETURN is prepended to the statement - * provided and should not be included - * @param returnStatement the return fragment of the cypher query. - */ - public void setReturnStatement(String returnStatement) { - this.returnStatement = returnStatement; - } - - /** - * An optional match fragment of the cypher query. MATCH is prepended to the statement - * provided and should not be included. - * @param matchStatement the match fragment of the cypher query - */ - public void setMatchStatement(String matchStatement) { - this.matchStatement = matchStatement; - } - - /** - * An optional where fragment of the cypher query. WHERE is prepended to the statement - * provided and should not be included. - * @param whereStatement where fragment of the cypher query - */ - public void setWhereStatement(String whereStatement) { - this.whereStatement = whereStatement; - } - - /** - * A list of properties to order the results by. This is required so that subsequent - * page requests pull back the segment of results correctly. ORDER BY is prepended to - * the statement provided and should not be included. - * @param orderByStatement order by fragment of the cypher query. - */ - public void setOrderByStatement(String orderByStatement) { - this.orderByStatement = orderByStatement; - } - - protected SessionFactory getSessionFactory() { - return sessionFactory; - } - - /** - * Establish the session factory for the reader. - * @param sessionFactory the factory to use for the reader. - */ - public void setSessionFactory(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; - } - - /** - * The object type to be returned from each call to {@link #read()} - * @param targetType the type of object to return. - */ - public void setTargetType(Class targetType) { - this.targetType = targetType; - } - - protected final Class getTargetType() { - return this.targetType; - } - - protected String generateLimitCypherQuery() { - StringBuilder query = new StringBuilder(128); - - query.append("START ").append(startStatement); - query.append(matchStatement != null ? " MATCH " + matchStatement : ""); - query.append(whereStatement != null ? " WHERE " + whereStatement : ""); - query.append(" RETURN ").append(returnStatement); - query.append(" ORDER BY ").append(orderByStatement); - query.append(" SKIP ").append(pageSize * page); - query.append(" LIMIT ").append(pageSize); - - String resultingQuery = query.toString(); - - if (logger.isDebugEnabled()) { - logger.debug(resultingQuery); - } - - return resultingQuery; - } - - /** - * Checks mandatory properties - * - * @see InitializingBean#afterPropertiesSet() - */ - @Override - public void afterPropertiesSet() throws Exception { - Assert.state(sessionFactory != null, "A SessionFactory is required"); - Assert.state(targetType != null, "The type to be returned is required"); - Assert.state(StringUtils.hasText(startStatement), "A START statement is required"); - Assert.state(StringUtils.hasText(returnStatement), "A RETURN statement is required"); - Assert.state(StringUtils.hasText(orderByStatement), "A ORDER BY statement is required"); - } - - @SuppressWarnings("unchecked") - @Override - protected Iterator doPageRead() { - Session session = getSessionFactory().openSession(); - - Iterable queryResults = session.query(getTargetType(), generateLimitCypherQuery(), getParameterValues()); - - if (queryResults != null) { - return queryResults.iterator(); - } - else { - return new ArrayList().iterator(); - } - } - -} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/Neo4jItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/Neo4jItemWriter.java deleted file mode 100644 index c9bcd35bf..000000000 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/Neo4jItemWriter.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2012-2024 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.item.data; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.neo4j.ogm.session.Session; -import org.neo4j.ogm.session.SessionFactory; - -import org.springframework.batch.item.Chunk; -import org.springframework.batch.item.ItemWriter; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.util.Assert; - -/** - *

    - * A {@link ItemWriter} implementation that writes to a Neo4j database. - *

    - * - *

    - * This writer is thread-safe once all properties are set (normal singleton behavior) so - * it can be used in multiple concurrent transactions. - *

    - * - * @author Michael Minella - * @author Glenn Renfro - * @author Mahmoud Ben Hassine - * @deprecated since 5.0 in favor of the item writer from ... - * - */ -@Deprecated -public class Neo4jItemWriter implements ItemWriter, InitializingBean { - - protected static final Log logger = LogFactory.getLog(Neo4jItemWriter.class); - - private boolean delete = false; - - private SessionFactory sessionFactory; - - /** - * Boolean flag indicating whether the writer should save or delete the item at write - * time. - * @param delete true if write should delete item, false if item should be saved. - * Default is false. - */ - public void setDelete(boolean delete) { - this.delete = delete; - } - - /** - * Establish the session factory that will be used to create {@link Session} instances - * for interacting with Neo4j. - * @param sessionFactory sessionFactory to be used. - */ - public void setSessionFactory(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; - } - - /** - * Checks mandatory properties - * - * @see InitializingBean#afterPropertiesSet() - */ - @Override - public void afterPropertiesSet() throws Exception { - Assert.state(this.sessionFactory != null, "A SessionFactory is required"); - } - - /** - * Write all items to the data store. - * - * @see org.springframework.batch.item.ItemWriter#write(Chunk) - */ - @Override - public void write(Chunk chunk) throws Exception { - if (!chunk.isEmpty()) { - doWrite(chunk); - } - } - - /** - * Performs the actual write using the template. This can be overridden by a subclass - * if necessary. - * @param items the list of items to be persisted. - */ - protected void doWrite(Chunk items) { - if (delete) { - delete(items); - } - else { - save(items); - } - } - - private void delete(Chunk items) { - Session session = this.sessionFactory.openSession(); - - for (T item : items) { - session.delete(item); - } - } - - private void save(Chunk items) { - Session session = this.sessionFactory.openSession(); - - for (T item : items) { - session.save(item); - } - } - -} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/MongoItemReaderBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/MongoItemReaderBuilder.java deleted file mode 100644 index 17747b821..000000000 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/MongoItemReaderBuilder.java +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright 2017-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.item.data.builder; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import org.springframework.batch.item.data.MongoItemReader; -import org.springframework.data.domain.Sort; -import org.springframework.data.mongodb.core.MongoOperations; -import org.springframework.data.mongodb.core.query.Query; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * A builder implementation for the {@link MongoItemReader} - * - * @author Glenn Renfro - * @author Mahmoud Ben Hassine - * @author Drummond Dawson - * @author Parikshit Dutta - * @since 4.0 - * @see MongoItemReader - * @deprecated Use {@link MongoPagingItemReaderBuilder} instead. Scheduled for removal in - * v5.3 or later. - */ -@Deprecated(since = "5.1", forRemoval = true) -public class MongoItemReaderBuilder { - - protected MongoOperations template; - - protected String jsonQuery; - - protected Class targetType; - - protected Map sorts; - - protected String hint; - - protected String fields; - - protected String collection; - - protected List parameterValues = new ArrayList<>(); - - protected int pageSize = 10; - - protected boolean saveState = true; - - protected String name; - - protected int maxItemCount = Integer.MAX_VALUE; - - protected int currentItemCount; - - protected Query query; - - /** - * Configure if the state of the - * {@link org.springframework.batch.item.ItemStreamSupport} should be persisted within - * the {@link org.springframework.batch.item.ExecutionContext} for restart purposes. - * @param saveState defaults to true - * @return The current instance of the builder. - */ - public MongoItemReaderBuilder saveState(boolean saveState) { - this.saveState = saveState; - - return this; - } - - /** - * The name used to calculate the key within the - * {@link org.springframework.batch.item.ExecutionContext}. Required if - * {@link #saveState(boolean)} is set to true. - * @param name name of the reader instance - * @return The current instance of the builder. - * @see org.springframework.batch.item.ItemStreamSupport#setName(String) - */ - public MongoItemReaderBuilder name(String name) { - this.name = name; - - return this; - } - - /** - * Configure the max number of items to be read. - * @param maxItemCount the max items to be read - * @return The current instance of the builder. - * @see org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader#setMaxItemCount(int) - */ - public MongoItemReaderBuilder maxItemCount(int maxItemCount) { - this.maxItemCount = maxItemCount; - - return this; - } - - /** - * Index for the current item. Used on restarts to indicate where to start from. - * @param currentItemCount current index - * @return this instance for method chaining - * @see org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader#setCurrentItemCount(int) - */ - public MongoItemReaderBuilder currentItemCount(int currentItemCount) { - this.currentItemCount = currentItemCount; - - return this; - } - - /** - * Used to perform operations against the MongoDB instance. Also handles the mapping - * of documents to objects. - * @param template the MongoOperations instance to use - * @see MongoOperations - * @return The current instance of the builder - * @see MongoItemReader#setTemplate(MongoOperations) - */ - public MongoItemReaderBuilder template(MongoOperations template) { - this.template = template; - - return this; - } - - /** - * A JSON formatted MongoDB jsonQuery. Parameterization of the provided jsonQuery is - * allowed via ?<index> placeholders where the <index> indicates the index - * of the parameterValue to substitute. - * @param query JSON formatted Mongo jsonQuery - * @return The current instance of the builder - * @see MongoItemReader#setQuery(String) - */ - public MongoItemReaderBuilder jsonQuery(String query) { - this.jsonQuery = query; - - return this; - } - - /** - * The type of object to be returned for each {@link MongoItemReader#read()} call. - * @param targetType the type of object to return - * @return The current instance of the builder - * @see MongoItemReader#setTargetType(Class) - */ - public MongoItemReaderBuilder targetType(Class targetType) { - this.targetType = targetType; - - return this; - } - - /** - * {@link List} of values to be substituted in for each of the parameters in the - * query. - * @param parameterValues values - * @return The current instance of the builder - * @see MongoItemReader#setParameterValues(List) - */ - public MongoItemReaderBuilder parameterValues(List parameterValues) { - this.parameterValues = parameterValues; - - return this; - } - - /** - * Values to be substituted in for each of the parameters in the query. - * @param parameterValues values - * @return The current instance of the builder - * @see MongoItemReader#setParameterValues(List) - */ - public MongoItemReaderBuilder parameterValues(Object... parameterValues) { - return parameterValues(Arrays.asList(parameterValues)); - } - - /** - * JSON defining the fields to be returned from the matching documents by MongoDB. - * @param fields JSON string that identifies the fields to sort by. - * @return The current instance of the builder - * @see MongoItemReader#setFields(String) - */ - public MongoItemReaderBuilder fields(String fields) { - this.fields = fields; - - return this; - } - - /** - * {@link Map} of property - * names/{@link org.springframework.data.domain.Sort.Direction} values to sort the - * input by. - * @param sorts map of properties and direction to sort each. - * @return The current instance of the builder - * @see MongoItemReader#setSort(Map) - */ - public MongoItemReaderBuilder sorts(Map sorts) { - this.sorts = sorts; - - return this; - } - - /** - * Establish an optional collection that can be queried. - * @param collection Mongo collection to be queried. - * @return The current instance of the builder - * @see MongoItemReader#setCollection(String) - */ - public MongoItemReaderBuilder collection(String collection) { - this.collection = collection; - - return this; - } - - /** - * JSON String telling MongoDB what index to use. - * @param hint string indicating what index to use. - * @return The current instance of the builder - * @see MongoItemReader#setHint(String) - */ - public MongoItemReaderBuilder hint(String hint) { - this.hint = hint; - - return this; - } - - /** - * The number of items to be read with each page. - * @param pageSize the number of items - * @return this instance for method chaining - * @see MongoItemReader#setPageSize(int) - */ - public MongoItemReaderBuilder pageSize(int pageSize) { - this.pageSize = pageSize; - - return this; - } - - /** - * Provide a Spring Data Mongo {@link Query}. This will take precedence over a JSON - * configured query. - * @param query Query to execute - * @return this instance for method chaining - * @see MongoItemReader#setQuery(Query) - */ - public MongoItemReaderBuilder query(Query query) { - this.query = query; - - return this; - } - - /** - * Validates and builds a {@link MongoItemReader}. - * @return a {@link MongoItemReader} - */ - public MongoItemReader build() { - Assert.notNull(this.template, "template is required."); - if (this.saveState) { - Assert.hasText(this.name, "A name is required when saveState is set to true"); - } - Assert.notNull(this.targetType, "targetType is required."); - Assert.state(StringUtils.hasText(this.jsonQuery) || this.query != null, "A query is required"); - - if (StringUtils.hasText(this.jsonQuery) || this.query != null) { - Assert.notNull(this.sorts, "sorts map is required."); - } - - MongoItemReader reader = new MongoItemReader<>(); - reader.setTemplate(this.template); - reader.setTargetType(this.targetType); - reader.setQuery(this.jsonQuery); - reader.setSort(this.sorts); - reader.setHint(this.hint); - reader.setFields(this.fields); - reader.setCollection(this.collection); - reader.setParameterValues(this.parameterValues); - reader.setQuery(this.query); - - reader.setPageSize(this.pageSize); - reader.setName(this.name); - reader.setSaveState(this.saveState); - reader.setCurrentItemCount(this.currentItemCount); - reader.setMaxItemCount(this.maxItemCount); - - return reader; - } - -} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/MongoItemWriterBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/MongoItemWriterBuilder.java index 4df60a7d4..e2cfdcdb4 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/MongoItemWriterBuilder.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/MongoItemWriterBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 the original author or authors. + * Copyright 2017-2025 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. @@ -37,23 +37,6 @@ public class MongoItemWriterBuilder { private Mode mode = Mode.UPSERT; - /** - * Indicates if the items being passed to the writer are to be saved or removed from - * the data store. If set to false (default), the items will be saved. If set to true, - * the items will be removed. - * @param delete removal indicator - * @return The current instance of the builder - * @see MongoItemWriter#setDelete(boolean) - * @deprecated Use {@link MongoItemWriterBuilder#mode(Mode)} instead. Scheduled for - * removal in v5.3 or later. - */ - @Deprecated(since = "5.1", forRemoval = true) - public MongoItemWriterBuilder delete(boolean delete) { - this.mode = (delete) ? Mode.REMOVE : Mode.UPSERT; - - return this; - } - /** * Set the operating {@link Mode} to be applied by this writer. Defaults to * {@link Mode#UPSERT}. diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/MongoPagingItemReaderBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/MongoPagingItemReaderBuilder.java index 286f043f0..480b3a7c9 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/MongoPagingItemReaderBuilder.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/MongoPagingItemReaderBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 the original author or authors. + * Copyright 2017-2025 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,6 +15,7 @@ */ package org.springframework.batch.item.data.builder; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -36,7 +37,35 @@ import org.springframework.util.StringUtils; * @author Parikshit Dutta * @since 5.1 */ -public class MongoPagingItemReaderBuilder extends MongoItemReaderBuilder { +public class MongoPagingItemReaderBuilder { + + protected MongoOperations template; + + protected String jsonQuery; + + protected Class targetType; + + protected Map sorts; + + protected String hint; + + protected String fields; + + protected String collection; + + protected List parameterValues = new ArrayList<>(); + + protected int pageSize = 10; + + protected boolean saveState = true; + + protected String name; + + protected int maxItemCount = Integer.MAX_VALUE; + + protected int currentItemCount; + + protected Query query; /** * Configure if the state of the @@ -228,7 +257,6 @@ public class MongoPagingItemReaderBuilder extends MongoItemReaderBuilder { return this; } - @Override public MongoPagingItemReader build() { Assert.notNull(this.template, "template is required."); if (this.saveState) { diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/Neo4jItemReaderBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/Neo4jItemReaderBuilder.java deleted file mode 100644 index 1884d2b18..000000000 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/Neo4jItemReaderBuilder.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright 2017-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.item.data.builder; - -import java.util.Map; - -import org.neo4j.ogm.session.SessionFactory; - -import org.springframework.batch.item.data.Neo4jItemReader; -import org.springframework.util.Assert; - -/** - * A builder for the {@link Neo4jItemReader}. - * - * @author Glenn Renfro - * @author Mahmoud Ben Hassine - * @since 4.0 - * @see Neo4jItemReader - * @deprecated since 5.0 in favor of the item reader builder from ... - */ -@Deprecated -public class Neo4jItemReaderBuilder { - - private SessionFactory sessionFactory; - - private String startStatement; - - private String returnStatement; - - private String matchStatement; - - private String whereStatement; - - private String orderByStatement; - - private Class targetType; - - private Map parameterValues; - - private int pageSize = 10; - - private boolean saveState = true; - - private String name; - - private int maxItemCount = Integer.MAX_VALUE; - - private int currentItemCount; - - /** - * Configure if the state of the - * {@link org.springframework.batch.item.ItemStreamSupport} should be persisted within - * the {@link org.springframework.batch.item.ExecutionContext} for restart purposes. - * @param saveState defaults to true - * @return The current instance of the builder. - */ - public Neo4jItemReaderBuilder saveState(boolean saveState) { - this.saveState = saveState; - - return this; - } - - /** - * The name used to calculate the key within the - * {@link org.springframework.batch.item.ExecutionContext}. Required if - * {@link #saveState(boolean)} is set to true. - * @param name name of the reader instance - * @return The current instance of the builder. - * @see org.springframework.batch.item.ItemStreamSupport#setName(String) - */ - public Neo4jItemReaderBuilder name(String name) { - this.name = name; - - return this; - } - - /** - * Configure the max number of items to be read. - * @param maxItemCount the max items to be read - * @return The current instance of the builder. - * @see org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader#setMaxItemCount(int) - */ - public Neo4jItemReaderBuilder maxItemCount(int maxItemCount) { - this.maxItemCount = maxItemCount; - - return this; - } - - /** - * Index for the current item. Used on restarts to indicate where to start from. - * @param currentItemCount current index - * @return this instance for method chaining - * @see org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader#setCurrentItemCount(int) - */ - public Neo4jItemReaderBuilder currentItemCount(int currentItemCount) { - this.currentItemCount = currentItemCount; - - return this; - } - - /** - * Establish the session factory for the reader. - * @param sessionFactory the factory to use for the reader. - * @return this instance for method chaining - * @see Neo4jItemReader#setSessionFactory(SessionFactory) - */ - public Neo4jItemReaderBuilder sessionFactory(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; - - return this; - } - - /** - * The number of items to be read with each page. - * @param pageSize the number of items - * @return this instance for method chaining - * @see Neo4jItemReader#setPageSize(int) - */ - public Neo4jItemReaderBuilder pageSize(int pageSize) { - this.pageSize = pageSize; - - return this; - } - - /** - * Optional parameters to be used in the cypher query. - * @param parameterValues the parameter values to be used in the cypher query - * @return this instance for method chaining - * @see Neo4jItemReader#setParameterValues(Map) - */ - public Neo4jItemReaderBuilder parameterValues(Map parameterValues) { - this.parameterValues = parameterValues; - - return this; - } - - /** - * The start segment of the cypher query. START is prepended to the statement provided - * and should not be included. - * @param startStatement the start fragment of the cypher query. - * @return this instance for method chaining - * @see Neo4jItemReader#setStartStatement(String) - */ - public Neo4jItemReaderBuilder startStatement(String startStatement) { - this.startStatement = startStatement; - - return this; - } - - /** - * The return statement of the cypher query. RETURN is prepended to the statement - * provided and should not be included - * @param returnStatement the return fragment of the cypher query. - * @return this instance for method chaining - * @see Neo4jItemReader#setReturnStatement(String) - */ - public Neo4jItemReaderBuilder returnStatement(String returnStatement) { - this.returnStatement = returnStatement; - - return this; - } - - /** - * An optional match fragment of the cypher query. MATCH is prepended to the statement - * provided and should not be included. - * @param matchStatement the match fragment of the cypher query - * @return this instance for method chaining - * @see Neo4jItemReader#setMatchStatement(String) - */ - public Neo4jItemReaderBuilder matchStatement(String matchStatement) { - this.matchStatement = matchStatement; - - return this; - } - - /** - * An optional where fragment of the cypher query. WHERE is prepended to the statement - * provided and should not be included. - * @param whereStatement where fragment of the cypher query - * @return this instance for method chaining - * @see Neo4jItemReader#setWhereStatement(String) - */ - public Neo4jItemReaderBuilder whereStatement(String whereStatement) { - this.whereStatement = whereStatement; - - return this; - } - - /** - * A list of properties to order the results by. This is required so that subsequent - * page requests pull back the segment of results correctly. ORDER BY is prepended to - * the statement provided and should not be included. - * @param orderByStatement order by fragment of the cypher query. - * @return this instance for method chaining - * @see Neo4jItemReader#setOrderByStatement(String) - */ - public Neo4jItemReaderBuilder orderByStatement(String orderByStatement) { - this.orderByStatement = orderByStatement; - - return this; - } - - /** - * The object type to be returned from each call to {@link Neo4jItemReader#read()} - * @param targetType the type of object to return. - * @return this instance for method chaining - * @see Neo4jItemReader#setTargetType(Class) - */ - public Neo4jItemReaderBuilder targetType(Class targetType) { - this.targetType = targetType; - - return this; - } - - /** - * Returns a fully constructed {@link Neo4jItemReader}. - * @return a new {@link Neo4jItemReader} - */ - public Neo4jItemReader build() { - if (this.saveState) { - Assert.hasText(this.name, "A name is required when saveState is set to true"); - } - Assert.notNull(this.sessionFactory, "sessionFactory is required."); - Assert.notNull(this.targetType, "targetType is required."); - Assert.hasText(this.startStatement, "startStatement is required."); - Assert.hasText(this.returnStatement, "returnStatement is required."); - Assert.hasText(this.orderByStatement, "orderByStatement is required."); - Assert.isTrue(this.pageSize > 0, "pageSize must be greater than zero"); - Assert.isTrue(this.maxItemCount > 0, "maxItemCount must be greater than zero"); - Assert.isTrue(this.maxItemCount > this.currentItemCount, "maxItemCount must be greater than currentItemCount"); - - Neo4jItemReader reader = new Neo4jItemReader<>(); - reader.setMatchStatement(this.matchStatement); - reader.setOrderByStatement(this.orderByStatement); - reader.setPageSize(this.pageSize); - reader.setParameterValues(this.parameterValues); - reader.setSessionFactory(this.sessionFactory); - reader.setTargetType(this.targetType); - reader.setStartStatement(this.startStatement); - reader.setReturnStatement(this.returnStatement); - reader.setWhereStatement(this.whereStatement); - reader.setName(this.name); - reader.setSaveState(this.saveState); - reader.setCurrentItemCount(this.currentItemCount); - reader.setMaxItemCount(this.maxItemCount); - - return reader; - } - -} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/Neo4jItemWriterBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/Neo4jItemWriterBuilder.java deleted file mode 100644 index 1e4e33479..000000000 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/Neo4jItemWriterBuilder.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2017-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.item.data.builder; - -import org.neo4j.ogm.session.Session; -import org.neo4j.ogm.session.SessionFactory; - -import org.springframework.batch.item.data.Neo4jItemWriter; -import org.springframework.util.Assert; - -/** - * A builder implementation for the {@link Neo4jItemWriter} - * - * @author Glenn Renfro - * @author Mahmoud Ben Hassine - * @since 4.0 - * @see Neo4jItemWriter - * @deprecated since 5.0 in favor of the item writer builder from ... - */ -@Deprecated -public class Neo4jItemWriterBuilder { - - private boolean delete = false; - - private SessionFactory sessionFactory; - - /** - * Boolean flag indicating whether the writer should save or delete the item at write - * time. - * @param delete true if write should delete item, false if item should be saved. - * Default is false. - * @return The current instance of the builder - * @see Neo4jItemWriter#setDelete(boolean) - */ - public Neo4jItemWriterBuilder delete(boolean delete) { - this.delete = delete; - - return this; - } - - /** - * Establish the session factory that will be used to create {@link Session} instances - * for interacting with Neo4j. - * @param sessionFactory sessionFactory to be used. - * @return The current instance of the builder - * @see Neo4jItemWriter#setSessionFactory(SessionFactory) - */ - public Neo4jItemWriterBuilder sessionFactory(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; - - return this; - } - - /** - * Validates and builds a {@link org.springframework.batch.item.data.Neo4jItemWriter}. - * @return a {@link Neo4jItemWriter} - */ - public Neo4jItemWriter build() { - Assert.notNull(sessionFactory, "sessionFactory is required."); - Neo4jItemWriter writer = new Neo4jItemWriter<>(); - writer.setDelete(this.delete); - writer.setSessionFactory(this.sessionFactory); - return writer; - } - -} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlPagingQueryUtils.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlPagingQueryUtils.java index 2ae66e438..265c6275c 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlPagingQueryUtils.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlPagingQueryUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2024 the original author or authors. + * Copyright 2006-2025 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. @@ -61,36 +61,6 @@ public abstract class SqlPagingQueryUtils { return sql.toString(); } - /** - * Generate SQL query string using a LIMIT clause - * @param provider {@link AbstractSqlPagingQueryProvider} providing the implementation - * specifics - * @param remainingPageQuery is this query for the remaining pages (true) as opposed - * to the first page (false) - * @param limitClause the implementation specific limit clause to be used - * @return the generated query - * @deprecated as of v5.0 in favor of - * {@link #generateLimitGroupedSqlQuery(AbstractSqlPagingQueryProvider, java.lang.String)} - */ - @Deprecated - public static String generateLimitGroupedSqlQuery(AbstractSqlPagingQueryProvider provider, - boolean remainingPageQuery, String limitClause) { - StringBuilder sql = new StringBuilder(); - sql.append("SELECT * "); - sql.append(" FROM ("); - sql.append("SELECT ").append(provider.getSelectClause()); - sql.append(" FROM ").append(provider.getFromClause()); - sql.append(provider.getWhereClause() == null ? "" : " WHERE " + provider.getWhereClause()); - buildGroupByClause(provider, sql); - sql.append(") AS MAIN_QRY "); - sql.append("WHERE "); - buildSortConditions(provider, sql); - sql.append(" ORDER BY ").append(buildSortClause(provider)); - sql.append(" ").append(limitClause); - - return sql.toString(); - } - /** * Generate SQL query string using a LIMIT clause * @param provider {@link AbstractSqlPagingQueryProvider} providing the implementation @@ -136,34 +106,6 @@ public abstract class SqlPagingQueryUtils { return sql.toString(); } - /** - * Generate SQL query string using a TOP clause - * @param provider {@link AbstractSqlPagingQueryProvider} providing the implementation - * specifics - * @param remainingPageQuery is this query for the remaining pages (true) as opposed - * to the first page (false) - * @param topClause the implementation specific top clause to be used - * @return the generated query - * @deprecated since v5.2 in favor of - * {@link #generateGroupedTopSqlQuery(AbstractSqlPagingQueryProvider, String)} - */ - @Deprecated - public static String generateGroupedTopSqlQuery(AbstractSqlPagingQueryProvider provider, boolean remainingPageQuery, - String topClause) { - StringBuilder sql = new StringBuilder(); - sql.append("SELECT ").append(topClause).append(" * FROM ("); - sql.append("SELECT ").append(provider.getSelectClause()); - sql.append(" FROM ").append(provider.getFromClause()); - sql.append(provider.getWhereClause() == null ? "" : " WHERE " + provider.getWhereClause()); - buildGroupByClause(provider, sql); - sql.append(") AS MAIN_QRY "); - sql.append("WHERE "); - buildSortConditions(provider, sql); - sql.append(" ORDER BY ").append(buildSortClause(provider)); - - return sql.toString(); - } - /** * Generate SQL query string using a TOP clause * @param provider {@link AbstractSqlPagingQueryProvider} providing the implementation diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlWindowingPagingQueryProvider.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlWindowingPagingQueryProvider.java deleted file mode 100644 index 00e0d0471..000000000 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlWindowingPagingQueryProvider.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2006-2024 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.item.database.support; - -import org.springframework.util.StringUtils; - -/** - * Generic Paging Query Provider using standard SQL:2003 windowing functions. These - * features are supported by DB2, Oracle, SQL Server 2005, Sybase and Apache Derby version - * 10.4.1.3 - * - * @author Thomas Risberg - * @author Michael Minella - * @since 2.0 - * @deprecated since 5.2.1 with no replacement. Scheduled for removal in 6.0. - */ -@Deprecated(forRemoval = true) -public class SqlWindowingPagingQueryProvider extends AbstractSqlPagingQueryProvider { - - @Override - public String generateFirstPageQuery(int pageSize) { - StringBuilder sql = new StringBuilder(); - sql.append("SELECT * FROM ( "); - sql.append("SELECT ") - .append(StringUtils.hasText(getOrderedQueryAlias()) ? getOrderedQueryAlias() + ".*, " : "*, "); - sql.append("ROW_NUMBER() OVER (").append(getOverClause()); - sql.append(") AS ROW_NUMBER"); - sql.append(getOverSubstituteClauseStart()); - sql.append(" FROM ") - .append(getFromClause()) - .append(getWhereClause() == null ? "" : " WHERE " + getWhereClause()); - sql.append(getGroupClause() == null ? "" : " GROUP BY " + getGroupClause()); - sql.append(getOverSubstituteClauseEnd()); - sql.append(") ") - .append(getSubQueryAlias()) - .append("WHERE ") - .append(extractTableAlias()) - .append("ROW_NUMBER <= ") - .append(pageSize); - sql.append(" ORDER BY ").append(SqlPagingQueryUtils.buildSortClause(this)); - - return sql.toString(); - } - - protected String getOrderedQueryAlias() { - return ""; - } - - protected Object getSubQueryAlias() { - return "AS TMP_SUB "; - } - - protected Object extractTableAlias() { - String alias = String.valueOf(getSubQueryAlias()); - if (StringUtils.hasText(alias) && alias.toUpperCase().startsWith("AS")) { - alias = alias.substring(3).trim() + "."; - } - return alias; - } - - @Override - public String generateRemainingPagesQuery(int pageSize) { - StringBuilder sql = new StringBuilder(); - sql.append("SELECT * FROM ( "); - sql.append("SELECT ") - .append(StringUtils.hasText(getOrderedQueryAlias()) ? getOrderedQueryAlias() + ".*, " : "*, "); - sql.append("ROW_NUMBER() OVER (").append(getOverClause()); - sql.append(") AS ROW_NUMBER"); - sql.append(getOverSubstituteClauseStart()); - sql.append(" FROM ").append(getFromClause()); - if (getWhereClause() != null) { - sql.append(" WHERE "); - sql.append(getWhereClause()); - } - - sql.append(getGroupClause() == null ? "" : " GROUP BY " + getGroupClause()); - sql.append(getOverSubstituteClauseEnd()); - sql.append(") ") - .append(getSubQueryAlias()) - .append("WHERE ") - .append(extractTableAlias()) - .append("ROW_NUMBER <= ") - .append(pageSize); - sql.append(" AND "); - SqlPagingQueryUtils.buildSortConditions(this, sql); - sql.append(" ORDER BY ").append(SqlPagingQueryUtils.buildSortClause(this)); - - return sql.toString(); - } - - protected String getOverClause() { - StringBuilder sql = new StringBuilder(); - - sql.append(" ORDER BY ").append(buildSortClause(this)); - - return sql.toString(); - } - - protected String getOverSubstituteClauseStart() { - return ""; - } - - protected String getOverSubstituteClauseEnd() { - return ""; - } - - /** - * Generates ORDER BY attributes based on the sort keys. - * @param provider the paging query provider - * @return a String that can be appended to an ORDER BY clause. - */ - private String buildSortClause(AbstractSqlPagingQueryProvider provider) { - return SqlPagingQueryUtils.buildSortClause(provider.getSortKeysWithoutAliases()); - } - -} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/listener/RepeatListenerSupport.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/listener/RepeatListenerSupport.java deleted file mode 100644 index cea6e890d..000000000 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/listener/RepeatListenerSupport.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2006-2021 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.repeat.listener; - -import org.springframework.batch.repeat.RepeatStatus; -import org.springframework.batch.repeat.RepeatContext; -import org.springframework.batch.repeat.RepeatListener; - -/** - * Empty method implementation of {@link RepeatListener}. - * - * @author Dave Syer - * @author Mahmoud Ben Hassine - * @deprecated as of v5.0 in favor of the default methods in {@link RepeatListener}. - */ -@Deprecated -public class RepeatListenerSupport implements RepeatListener { - - @Override - public void before(RepeatContext context) { - } - - @Override - public void after(RepeatContext context, RepeatStatus result) { - } - - @Override - public void close(RepeatContext context) { - } - - @Override - public void onError(RepeatContext context, Throwable e) { - } - - @Override - public void open(RepeatContext context) { - } - -} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/TaskExecutorRepeatTemplate.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/TaskExecutorRepeatTemplate.java index 44dba5b44..005fefe4f 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/TaskExecutorRepeatTemplate.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/TaskExecutorRepeatTemplate.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2025 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. @@ -59,25 +59,6 @@ public class TaskExecutorRepeatTemplate extends RepeatTemplate { private TaskExecutor taskExecutor = new SyncTaskExecutor(); - /** - * Public setter for the throttle limit. The throttle limit is the largest number of - * concurrent tasks that can be executing at one time - if a new task arrives and the - * throttle limit is breached we wait for one of the executing tasks to finish before - * submitting the new one to the {@link TaskExecutor}. Default value is - * {@link #DEFAULT_THROTTLE_LIMIT}. N.B. when used with a thread pooled - * {@link TaskExecutor} the thread pool might prevent the throttle limit actually - * being reached (so make the core pool size larger than the throttle limit if - * possible). - * @param throttleLimit the throttleLimit to set. - * @deprecated since 5.0, scheduled for removal in 6.0. Use a pooled - * {@link TaskExecutor} implemenation with a limited capacity of its task queue - * instead. - */ - @Deprecated(since = "5.0", forRemoval = true) - public void setThrottleLimit(int throttleLimit) { - this.throttleLimit = throttleLimit; - } - /** * Setter for task executor to be used to run the individual item callbacks. * @param taskExecutor a TaskExecutor diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/SystemPropertyInitializer.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/SystemPropertyInitializer.java deleted file mode 100644 index ea2ff9bac..000000000 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/SystemPropertyInitializer.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2006-2024 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.support; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.util.Assert; - -/** - * Helper class that sets up a System property with a default value. A System property is - * created with the specified key name, and default value (i.e. if the property already - * exists it is not changed). - * - * @author Dave Syer - * @deprecated since 5.2 with no replacement. - */ -@Deprecated(since = "5.2.0", forRemoval = true) -public class SystemPropertyInitializer implements InitializingBean { - - /** - * Name of system property used by default. - */ - public static final String ENVIRONMENT = "org.springframework.batch.support.SystemPropertyInitializer.ENVIRONMENT"; - - private String keyName = ENVIRONMENT; - - private String defaultValue; - - /** - * Set the key name for the System property that is created. Defaults to - * {@link #ENVIRONMENT}. - * @param keyName the key name to set - */ - public void setKeyName(String keyName) { - this.keyName = keyName; - } - - /** - * Mandatory property specifying the default value of the System property. - * @param defaultValue the default value to set - */ - public void setDefaultValue(String defaultValue) { - this.defaultValue = defaultValue; - } - - /** - * Sets the System property with the provided name and default value. - * - * @see InitializingBean#afterPropertiesSet() - */ - @Override - public void afterPropertiesSet() throws Exception { - Assert.state(defaultValue != null || System.getProperty(keyName) != null, - "Either a default value must be specified or the value should already be set for System property: " - + keyName); - System.setProperty(keyName, System.getProperty(keyName, defaultValue)); - } - -} diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/MongoItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/MongoItemWriterTests.java index 55919f242..1ed55109a 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/MongoItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/MongoItemWriterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2022 the original author or authors. + * Copyright 2013-2025 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. @@ -199,7 +199,7 @@ class MongoItemWriterTests { @Test void testRemoveNoObjectIdNoCollection() throws Exception { - writer.setDelete(true); + writer.setMode(Mode.REMOVE); Chunk items = Chunk.of(new Item("Foo"), new Item("Bar")); writer.write(items); @@ -210,7 +210,7 @@ class MongoItemWriterTests { @Test void testRemoveNoObjectIdWithCollection() throws Exception { - writer.setDelete(true); + writer.setMode(Mode.REMOVE); Chunk items = Chunk.of(new Item("Foo"), new Item("Bar")); writer.setCollection("collection"); @@ -222,7 +222,7 @@ class MongoItemWriterTests { @Test void testRemoveNoTransactionNoCollection() throws Exception { - writer.setDelete(true); + writer.setMode(Mode.REMOVE); Chunk items = Chunk.of(new Item(1), new Item(2)); writer.write(items); @@ -233,7 +233,7 @@ class MongoItemWriterTests { @Test void testRemoveNoTransactionWithCollection() throws Exception { - writer.setDelete(true); + writer.setMode(Mode.REMOVE); Chunk items = Chunk.of(new Item(1), new Item(2)); writer.setCollection("collection"); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/Neo4jItemReaderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/Neo4jItemReaderTests.java deleted file mode 100644 index 34d279181..000000000 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/Neo4jItemReaderTests.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright 2013-2022 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.item.data; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.neo4j.ogm.session.Session; -import org.neo4j.ogm.session.SessionFactory; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.isNull; -import static org.mockito.Mockito.when; - -@SuppressWarnings("deprecation") -@ExtendWith(MockitoExtension.class) -class Neo4jItemReaderTests { - - @Mock - private Iterable result; - - @Mock - private SessionFactory sessionFactory; - - @Mock - private Session session; - - private Neo4jItemReader buildSessionBasedReader() throws Exception { - Neo4jItemReader reader = new Neo4jItemReader<>(); - - reader.setSessionFactory(this.sessionFactory); - reader.setTargetType(String.class); - reader.setStartStatement("n=node(*)"); - reader.setReturnStatement("*"); - reader.setOrderByStatement("n.age"); - reader.setPageSize(50); - reader.afterPropertiesSet(); - - return reader; - } - - @Test - void testAfterPropertiesSet() throws Exception { - - Neo4jItemReader reader = new Neo4jItemReader<>(); - - Exception exception = assertThrows(IllegalStateException.class, reader::afterPropertiesSet); - assertEquals("A SessionFactory is required", exception.getMessage()); - - reader.setSessionFactory(this.sessionFactory); - - exception = assertThrows(IllegalStateException.class, reader::afterPropertiesSet); - assertEquals("The type to be returned is required", exception.getMessage()); - - reader.setTargetType(String.class); - - exception = assertThrows(IllegalStateException.class, reader::afterPropertiesSet); - assertEquals("A START statement is required", exception.getMessage()); - - reader.setStartStatement("n=node(*)"); - - exception = assertThrows(IllegalStateException.class, reader::afterPropertiesSet); - assertEquals("A RETURN statement is required", exception.getMessage()); - - reader.setReturnStatement("n.name, n.phone"); - - exception = assertThrows(IllegalStateException.class, reader::afterPropertiesSet); - assertEquals("A ORDER BY statement is required", exception.getMessage()); - - reader.setOrderByStatement("n.age"); - reader.afterPropertiesSet(); - - reader = new Neo4jItemReader<>(); - reader.setSessionFactory(this.sessionFactory); - reader.setTargetType(String.class); - reader.setStartStatement("n=node(*)"); - reader.setReturnStatement("n.name, n.phone"); - reader.setOrderByStatement("n.age"); - - reader.afterPropertiesSet(); - } - - @Test - void testNullResultsWithSession() throws Exception { - - Neo4jItemReader itemReader = buildSessionBasedReader(); - - ArgumentCaptor query = ArgumentCaptor.forClass(String.class); - - when(this.sessionFactory.openSession()).thenReturn(this.session); - when(this.session.query(eq(String.class), query.capture(), isNull())).thenReturn(null); - - assertFalse(itemReader.doPageRead().hasNext()); - assertEquals("START n=node(*) RETURN * ORDER BY n.age SKIP 0 LIMIT 50", query.getValue()); - } - - @Test - void testNoResultsWithSession() throws Exception { - Neo4jItemReader itemReader = buildSessionBasedReader(); - ArgumentCaptor query = ArgumentCaptor.forClass(String.class); - - when(this.sessionFactory.openSession()).thenReturn(this.session); - when(this.session.query(eq(String.class), query.capture(), isNull())).thenReturn(result); - when(result.iterator()).thenReturn(Collections.emptyIterator()); - - assertFalse(itemReader.doPageRead().hasNext()); - assertEquals("START n=node(*) RETURN * ORDER BY n.age SKIP 0 LIMIT 50", query.getValue()); - } - - @Test - void testResultsWithMatchAndWhereWithSession() throws Exception { - Neo4jItemReader itemReader = buildSessionBasedReader(); - itemReader.setMatchStatement("n -- m"); - itemReader.setWhereStatement("has(n.name)"); - itemReader.setReturnStatement("m"); - itemReader.afterPropertiesSet(); - - when(this.sessionFactory.openSession()).thenReturn(this.session); - when(this.session.query(String.class, - "START n=node(*) MATCH n -- m WHERE has(n.name) RETURN m ORDER BY n.age SKIP 0 LIMIT 50", null)) - .thenReturn(result); - when(result.iterator()).thenReturn(Arrays.asList("foo", "bar", "baz").iterator()); - - assertTrue(itemReader.doPageRead().hasNext()); - } - - @Test - void testResultsWithMatchAndWhereWithParametersWithSession() throws Exception { - Neo4jItemReader itemReader = buildSessionBasedReader(); - Map params = new HashMap<>(); - params.put("foo", "bar"); - itemReader.setParameterValues(params); - itemReader.setMatchStatement("n -- m"); - itemReader.setWhereStatement("has(n.name)"); - itemReader.setReturnStatement("m"); - itemReader.afterPropertiesSet(); - - when(this.sessionFactory.openSession()).thenReturn(this.session); - when(this.session.query(String.class, - "START n=node(*) MATCH n -- m WHERE has(n.name) RETURN m ORDER BY n.age SKIP 0 LIMIT 50", params)) - .thenReturn(result); - when(result.iterator()).thenReturn(Arrays.asList("foo", "bar", "baz").iterator()); - - assertTrue(itemReader.doPageRead().hasNext()); - } - -} diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/Neo4jItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/Neo4jItemWriterTests.java deleted file mode 100644 index 2a9650f60..000000000 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/Neo4jItemWriterTests.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2013-2022 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.item.data; - -import org.junit.jupiter.api.Test; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoSettings; -import org.mockito.quality.Strictness; -import org.neo4j.ogm.session.Session; -import org.neo4j.ogm.session.SessionFactory; - -import org.springframework.batch.item.Chunk; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoInteractions; -import static org.mockito.Mockito.when; - -@SuppressWarnings("deprecation") -@MockitoSettings(strictness = Strictness.LENIENT) -class Neo4jItemWriterTests { - - private Neo4jItemWriter writer; - - @Mock - private SessionFactory sessionFactory; - - @Mock - private Session session; - - @Test - void testAfterPropertiesSet() throws Exception { - - writer = new Neo4jItemWriter<>(); - - Exception exception = assertThrows(IllegalStateException.class, writer::afterPropertiesSet); - assertEquals("A SessionFactory is required", exception.getMessage()); - - writer.setSessionFactory(this.sessionFactory); - - writer.afterPropertiesSet(); - - writer = new Neo4jItemWriter<>(); - - writer.setSessionFactory(this.sessionFactory); - - writer.afterPropertiesSet(); - } - - @Test - void testWriteNoItemsWithSession() throws Exception { - writer = new Neo4jItemWriter<>(); - - writer.setSessionFactory(this.sessionFactory); - writer.afterPropertiesSet(); - - when(this.sessionFactory.openSession()).thenReturn(this.session); - writer.write(new Chunk<>()); - - verifyNoInteractions(this.session); - } - - @Test - void testWriteItemsWithSession() throws Exception { - writer = new Neo4jItemWriter<>(); - - writer.setSessionFactory(this.sessionFactory); - writer.afterPropertiesSet(); - - Chunk items = new Chunk<>(); - items.add("foo"); - items.add("bar"); - - when(this.sessionFactory.openSession()).thenReturn(this.session); - writer.write(items); - - verify(this.session).save("foo"); - verify(this.session).save("bar"); - } - - @Test - void testDeleteItemsWithSession() throws Exception { - writer = new Neo4jItemWriter<>(); - - writer.setSessionFactory(this.sessionFactory); - writer.afterPropertiesSet(); - - Chunk items = new Chunk<>(); - items.add("foo"); - items.add("bar"); - - writer.setDelete(true); - - when(this.sessionFactory.openSession()).thenReturn(this.session); - writer.write(items); - - verify(this.session).delete("foo"); - verify(this.session).delete("bar"); - } - -} diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/MongoItemWriterBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/MongoItemWriterBuilderTests.java index 699dd40f5..13b4f58bf 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/MongoItemWriterBuilderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/MongoItemWriterBuilderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2022 the original author or authors. + * Copyright 2017-2025 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. @@ -112,7 +112,9 @@ class MongoItemWriterBuilderTests { @Test void testDelete() throws Exception { - MongoItemWriter writer = new MongoItemWriterBuilder().template(this.template).delete(true).build(); + MongoItemWriter writer = new MongoItemWriterBuilder().template(this.template) + .mode(MongoItemWriter.Mode.REMOVE) + .build(); writer.write(this.removeItems); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/Neo4jItemReaderBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/Neo4jItemReaderBuilderTests.java deleted file mode 100644 index 08d7dacc5..000000000 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/Neo4jItemReaderBuilderTests.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright 2017-2022 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.item.data.builder; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.neo4j.ogm.session.Session; -import org.neo4j.ogm.session.SessionFactory; - -import org.springframework.batch.item.data.Neo4jItemReader; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.Mockito.when; - -/** - * @author Glenn Renfro - */ -@SuppressWarnings("deprecation") -@ExtendWith(MockitoExtension.class) -class Neo4jItemReaderBuilderTests { - - @Mock - private Iterable result; - - @Mock - private SessionFactory sessionFactory; - - @Mock - private Session session; - - @Test - void testFullyQualifiedItemReader() throws Exception { - Neo4jItemReader itemReader = new Neo4jItemReaderBuilder().sessionFactory(this.sessionFactory) - .targetType(String.class) - .startStatement("n=node(*)") - .orderByStatement("n.age") - .pageSize(50) - .name("bar") - .matchStatement("n -- m") - .whereStatement("has(n.name)") - .returnStatement("m") - .build(); - - when(this.sessionFactory.openSession()).thenReturn(this.session); - when(this.session.query(String.class, - "START n=node(*) MATCH n -- m WHERE has(n.name) RETURN m ORDER BY n.age SKIP 0 LIMIT 50", null)) - .thenReturn(result); - when(result.iterator()).thenReturn(Arrays.asList("foo", "bar", "baz").iterator()); - - assertEquals("foo", itemReader.read(), "The expected value was not returned by reader."); - assertEquals("bar", itemReader.read(), "The expected value was not returned by reader."); - assertEquals("baz", itemReader.read(), "The expected value was not returned by reader."); - } - - @Test - void testCurrentSize() throws Exception { - Neo4jItemReader itemReader = new Neo4jItemReaderBuilder().sessionFactory(this.sessionFactory) - .targetType(String.class) - .startStatement("n=node(*)") - .orderByStatement("n.age") - .pageSize(50) - .name("bar") - .returnStatement("m") - .currentItemCount(0) - .maxItemCount(1) - .build(); - - when(this.sessionFactory.openSession()).thenReturn(this.session); - when(this.session.query(String.class, "START n=node(*) RETURN m ORDER BY n.age SKIP 0 LIMIT 50", null)) - .thenReturn(result); - when(result.iterator()).thenReturn(Arrays.asList("foo", "bar", "baz").iterator()); - - assertEquals("foo", itemReader.read(), "The expected value was not returned by reader."); - assertNull(itemReader.read(), "The expected value was not should be null."); - } - - @Test - void testResultsWithMatchAndWhereWithParametersWithSession() throws Exception { - Map params = new HashMap<>(); - params.put("foo", "bar"); - Neo4jItemReader itemReader = new Neo4jItemReaderBuilder().sessionFactory(this.sessionFactory) - .targetType(String.class) - .startStatement("n=node(*)") - .returnStatement("*") - .orderByStatement("n.age") - .pageSize(50) - .name("foo") - .parameterValues(params) - .matchStatement("n -- m") - .whereStatement("has(n.name)") - .returnStatement("m") - .build(); - - when(this.sessionFactory.openSession()).thenReturn(this.session); - when(this.session.query(String.class, - "START n=node(*) MATCH n -- m WHERE has(n.name) RETURN m ORDER BY n.age SKIP 0 LIMIT 50", params)) - .thenReturn(result); - when(result.iterator()).thenReturn(Arrays.asList("foo", "bar", "baz").iterator()); - - assertEquals("foo", itemReader.read(), "The expected value was not returned by reader."); - } - - @Test - void testNoSessionFactory() { - var builder = new Neo4jItemReaderBuilder().targetType(String.class) - .startStatement("n=node(*)") - .returnStatement("*") - .orderByStatement("n.age") - .pageSize(50) - .name("bar"); - Exception exception = assertThrows(IllegalArgumentException.class, builder::build); - assertEquals("sessionFactory is required.", exception.getMessage()); - } - - @Test - void testZeroPageSize() { - validateExceptionMessage(new Neo4jItemReaderBuilder().sessionFactory(this.sessionFactory) - .targetType(String.class) - .startStatement("n=node(*)") - .returnStatement("*") - .orderByStatement("n.age") - .pageSize(0) - .name("foo") - .matchStatement("n -- m") - .whereStatement("has(n.name)") - .returnStatement("m"), "pageSize must be greater than zero"); - } - - @Test - void testZeroMaxItemCount() { - validateExceptionMessage(new Neo4jItemReaderBuilder().sessionFactory(this.sessionFactory) - .targetType(String.class) - .startStatement("n=node(*)") - .returnStatement("*") - .orderByStatement("n.age") - .pageSize(5) - .maxItemCount(0) - .name("foo") - .matchStatement("n -- m") - .whereStatement("has(n.name)") - .returnStatement("m"), "maxItemCount must be greater than zero"); - } - - @Test - void testCurrentItemCountGreaterThanMaxItemCount() { - validateExceptionMessage(new Neo4jItemReaderBuilder().sessionFactory(this.sessionFactory) - .targetType(String.class) - .startStatement("n=node(*)") - .returnStatement("*") - .orderByStatement("n.age") - .pageSize(5) - .maxItemCount(5) - .currentItemCount(6) - .name("foo") - .matchStatement("n -- m") - .whereStatement("has(n.name)") - .returnStatement("m"), "maxItemCount must be greater than currentItemCount"); - } - - @Test - void testNullName() { - validateExceptionMessage(new Neo4jItemReaderBuilder().sessionFactory(this.sessionFactory) - .targetType(String.class) - .startStatement("n=node(*)") - .returnStatement("*") - .orderByStatement("n.age") - .pageSize(50), "A name is required when saveState is set to true"); - - // tests that name is not required if saveState is set to false. - new Neo4jItemReaderBuilder().sessionFactory(this.sessionFactory) - .targetType(String.class) - .startStatement("n=node(*)") - .returnStatement("*") - .orderByStatement("n.age") - .saveState(false) - .pageSize(50) - .build(); - } - - @Test - void testNullTargetType() { - validateExceptionMessage(new Neo4jItemReaderBuilder().sessionFactory(this.sessionFactory) - .startStatement("n=node(*)") - .returnStatement("*") - .orderByStatement("n.age") - .pageSize(50) - .name("bar") - .matchStatement("n -- m") - .whereStatement("has(n.name)") - .returnStatement("m"), "targetType is required."); - } - - @Test - void testNullStartStatement() { - validateExceptionMessage(new Neo4jItemReaderBuilder().sessionFactory(this.sessionFactory) - .targetType(String.class) - .returnStatement("*") - .orderByStatement("n.age") - .pageSize(50) - .name("bar") - .matchStatement("n -- m") - .whereStatement("has(n.name)") - .returnStatement("m"), "startStatement is required."); - } - - @Test - void testNullReturnStatement() { - validateExceptionMessage(new Neo4jItemReaderBuilder().sessionFactory(this.sessionFactory) - .targetType(String.class) - .startStatement("n=node(*)") - .orderByStatement("n.age") - .pageSize(50) - .name("bar") - .matchStatement("n -- m") - .whereStatement("has(n.name)"), "returnStatement is required."); - } - - @Test - void testNullOrderByStatement() { - validateExceptionMessage(new Neo4jItemReaderBuilder().sessionFactory(this.sessionFactory) - .targetType(String.class) - .startStatement("n=node(*)") - .returnStatement("*") - .pageSize(50) - .name("bar") - .matchStatement("n -- m") - .whereStatement("has(n.name)") - .returnStatement("m"), "orderByStatement is required."); - } - - private void validateExceptionMessage(Neo4jItemReaderBuilder builder, String message) { - Exception exception = assertThrows(IllegalArgumentException.class, builder::build); - assertEquals(message, exception.getMessage()); - } - -} diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/Neo4jItemWriterBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/Neo4jItemWriterBuilderTests.java deleted file mode 100644 index 3f6629483..000000000 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/Neo4jItemWriterBuilderTests.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2017-2022 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.item.data.builder; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.neo4j.ogm.session.Session; -import org.neo4j.ogm.session.SessionFactory; - -import org.springframework.batch.item.Chunk; -import org.springframework.batch.item.data.Neo4jItemWriter; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * @author Glenn Renfro - * @author Mahmoud Ben Hassine - */ -@SuppressWarnings("deprecation") -@ExtendWith(MockitoExtension.class) -class Neo4jItemWriterBuilderTests { - - @Mock - private SessionFactory sessionFactory; - - @Mock - private Session session; - - @Test - void testBasicWriter() throws Exception { - Neo4jItemWriter writer = new Neo4jItemWriterBuilder().sessionFactory(this.sessionFactory) - .build(); - Chunk items = new Chunk<>(); - items.add("foo"); - items.add("bar"); - - when(this.sessionFactory.openSession()).thenReturn(this.session); - writer.write(items); - - verify(this.session).save("foo"); - verify(this.session).save("bar"); - verify(this.session, never()).delete("foo"); - verify(this.session, never()).delete("bar"); - } - - @Test - void testBasicDelete() throws Exception { - Neo4jItemWriter writer = new Neo4jItemWriterBuilder().delete(true) - .sessionFactory(this.sessionFactory) - .build(); - Chunk items = new Chunk<>(); - items.add("foo"); - items.add("bar"); - - when(this.sessionFactory.openSession()).thenReturn(this.session); - writer.write(items); - - verify(this.session).delete("foo"); - verify(this.session).delete("bar"); - verify(this.session, never()).save("foo"); - verify(this.session, never()).save("bar"); - } - - @Test - void testNoSessionFactory() { - Exception exception = assertThrows(IllegalArgumentException.class, - () -> new Neo4jItemWriterBuilder().build()); - assertEquals("sessionFactory is required.", exception.getMessage()); - } - -} diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/SqlWindowingPagingQueryProviderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/SqlWindowingPagingQueryProviderTests.java deleted file mode 100644 index cd58aecfb..000000000 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/SqlWindowingPagingQueryProviderTests.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2006-2024 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.item.database.support; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * @author Thomas Risberg - * @author Michael Minella - */ -class SqlWindowingPagingQueryProviderTests extends AbstractSqlPagingQueryProviderTests { - - @SuppressWarnings("removal") - SqlWindowingPagingQueryProviderTests() { - pagingQueryProvider = new SqlWindowingPagingQueryProvider(); - } - - @Test - @Override - void testGenerateFirstPageQuery() { - String sql = "SELECT * FROM ( SELECT *, ROW_NUMBER() OVER ( ORDER BY id ASC) AS ROW_NUMBER FROM foo WHERE bar = 1) AS TMP_SUB WHERE TMP_SUB.ROW_NUMBER <= 100 ORDER BY id ASC"; - String s = pagingQueryProvider.generateFirstPageQuery(pageSize); - assertEquals(sql, s); - } - - @Test - @Override - void testGenerateRemainingPagesQuery() { - String sql = "SELECT * FROM ( SELECT *, ROW_NUMBER() OVER ( ORDER BY id ASC) AS ROW_NUMBER FROM foo WHERE bar = 1) AS TMP_SUB WHERE TMP_SUB.ROW_NUMBER <= 100 AND ((id > ?)) ORDER BY id ASC"; - String s = pagingQueryProvider.generateRemainingPagesQuery(pageSize); - assertEquals(sql, s); - } - - @Test - @Override - void testGenerateFirstPageQueryWithGroupBy() { - pagingQueryProvider.setGroupClause("dep"); - String sql = "SELECT * FROM ( SELECT *, ROW_NUMBER() OVER ( ORDER BY id ASC) AS ROW_NUMBER FROM foo WHERE bar = 1 GROUP BY dep) AS TMP_SUB WHERE TMP_SUB.ROW_NUMBER <= 100 ORDER BY id ASC"; - String s = pagingQueryProvider.generateFirstPageQuery(pageSize); - assertEquals(sql, s); - } - - @Test - @Override - void testGenerateRemainingPagesQueryWithGroupBy() { - pagingQueryProvider.setGroupClause("dep"); - String sql = "SELECT * FROM ( SELECT *, ROW_NUMBER() OVER ( ORDER BY id ASC) AS ROW_NUMBER FROM foo WHERE bar = 1 GROUP BY dep) AS TMP_SUB WHERE TMP_SUB.ROW_NUMBER <= 100 AND ((id > ?)) ORDER BY id ASC"; - String s = pagingQueryProvider.generateRemainingPagesQuery(pageSize); - assertEquals(sql, s); - } - - @Override - String getFirstPageSqlWithMultipleSortKeys() { - return "SELECT * FROM ( SELECT *, ROW_NUMBER() OVER ( ORDER BY name ASC, id DESC) AS ROW_NUMBER FROM foo WHERE bar = 1) AS TMP_SUB WHERE TMP_SUB.ROW_NUMBER <= 100 ORDER BY name ASC, id DESC"; - } - - @Override - String getRemainingSqlWithMultipleSortKeys() { - return "SELECT * FROM ( SELECT *, ROW_NUMBER() OVER ( ORDER BY name ASC, id DESC) AS ROW_NUMBER FROM foo WHERE bar = 1) AS TMP_SUB WHERE TMP_SUB.ROW_NUMBER <= 100 AND ((name > ?) OR (name = ? AND id < ?)) ORDER BY name ASC, id DESC"; - } - -} diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/TaskExecutorRepeatTemplateAsynchronousTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/TaskExecutorRepeatTemplateAsynchronousTests.java index 5d6dd5292..89a393ae4 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/TaskExecutorRepeatTemplateAsynchronousTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/TaskExecutorRepeatTemplateAsynchronousTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2025 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. @@ -159,7 +159,6 @@ class TaskExecutorRepeatTemplateAsynchronousTests extends AbstractTradeBatchTest SimpleAsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor(); taskExecutor.setConcurrencyLimit(300); template.setTaskExecutor(taskExecutor); - template.setThrottleLimit(throttleLimit); String threadName = Thread.currentThread().getName(); Set threadNames = ConcurrentHashMap.newKeySet(); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/TaskExecutorRepeatTemplateBulkAsynchronousTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/TaskExecutorRepeatTemplateBulkAsynchronousTests.java index cb39231a6..47dd4e892 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/TaskExecutorRepeatTemplateBulkAsynchronousTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/TaskExecutorRepeatTemplateBulkAsynchronousTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2025 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. @@ -18,12 +18,10 @@ package org.springframework.batch.repeat.support; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.atomic.AtomicInteger; import org.apache.commons.logging.Log; @@ -35,7 +33,6 @@ import org.springframework.batch.repeat.RepeatCallback; import org.springframework.batch.repeat.RepeatContext; import org.springframework.batch.repeat.RepeatStatus; import org.springframework.batch.repeat.policy.SimpleCompletionPolicy; -import org.springframework.core.task.SimpleAsyncTaskExecutor; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; /** @@ -54,8 +51,6 @@ class TaskExecutorRepeatTemplateBulkAsynchronousTests { private int total = 1000; - private int throttleLimit = 30; - private volatile int early = Integer.MAX_VALUE; private volatile int error = Integer.MAX_VALUE; @@ -77,7 +72,6 @@ class TaskExecutorRepeatTemplateBulkAsynchronousTests { threadPool.setQueueCapacity(0); threadPool.afterPropertiesSet(); template.setTaskExecutor(threadPool); - template.setThrottleLimit(throttleLimit); items = Collections.synchronizedList(new ArrayList<>()); @@ -117,102 +111,6 @@ class TaskExecutorRepeatTemplateBulkAsynchronousTests { threadPool.destroy(); } - @Test - void testThrottleLimit() { - - template.iterate(callback); - int frequency = Collections.frequency(items, null); - assertEquals(total, items.size() - frequency); - assertTrue(frequency > 1); - assertTrue(frequency <= throttleLimit + 1); - - } - - @Test - void testThrottleLimitEarlyFinish() { - - early = 2; - - template.iterate(callback); - int frequency = Collections.frequency(items, null); - assertEquals(total, items.size() - frequency); - assertTrue(frequency > 1); - assertTrue(frequency <= throttleLimit + 1); - - } - - @Test - void testThrottleLimitEarlyFinishThreadStarvation() { - - early = 2; - ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); - // Set the concurrency limit below the throttle limit for possible - // starvation condition - taskExecutor.setMaxPoolSize(20); - taskExecutor.setCorePoolSize(10); - taskExecutor.setQueueCapacity(0); - // This is the most sensible setting, otherwise the bookkeeping in - // ResultHolderResultQueue gets out of whack when tasks are aborted. - taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); - taskExecutor.afterPropertiesSet(); - template.setTaskExecutor(taskExecutor); - - template.iterate(callback); - int frequency = Collections.frequency(items, null); - // Extra tasks will be submitted before the termination is detected - assertEquals(total, items.size() - frequency); - assertTrue(frequency <= throttleLimit + 1); - - taskExecutor.destroy(); - - } - - @Test - void testThrottleLimitEarlyFinishOneThread() { - - early = 4; - SimpleAsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor(); - taskExecutor.setConcurrencyLimit(1); - - // This is kind of slow with only one thread, so reduce size: - throttleLimit = 10; - total = 20; - - template.setThrottleLimit(throttleLimit); - template.setTaskExecutor(taskExecutor); - - template.iterate(callback); - int frequency = Collections.frequency(items, null); - assertEquals(total, items.size() - frequency); - assertTrue(frequency <= throttleLimit + 1); - - } - - @Test - void testThrottleLimitWithEarlyCompletion() { - - early = 2; - template.setCompletionPolicy(new SimpleCompletionPolicy(10)); - - template.iterate(callback); - int frequency = Collections.frequency(items, null); - assertEquals(10, items.size() - frequency); - assertEquals(0, frequency); - - } - - @Test - void testThrottleLimitWithError() { - - error = 50; - - Exception exception = assertThrows(Exception.class, () -> template.iterate(callback)); - assertEquals("Planned", exception.getMessage()); - int frequency = Collections.frequency(items, null); - assertEquals(0, frequency); - - } - @Test void testErrorThrownByCallback() { diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/TaskExecutorRepeatTemplateTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/TaskExecutorRepeatTemplateTests.java index c9245d717..32926ce55 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/TaskExecutorRepeatTemplateTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/TaskExecutorRepeatTemplateTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 the original author or authors. + * Copyright 2006-2025 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. @@ -16,12 +16,9 @@ package org.springframework.batch.repeat.support; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; - -import org.junit.jupiter.api.Test; - /** * @author Dave Syer + * @author Mahmoud Ben Hassine */ public class TaskExecutorRepeatTemplateTests extends SimpleRepeatTemplateTests { @@ -30,10 +27,4 @@ public class TaskExecutorRepeatTemplateTests extends SimpleRepeatTemplateTests { return new TaskExecutorRepeatTemplate(); } - @Test - void testSetThrottleLimit() { - // no check for illegal values - assertDoesNotThrow(() -> new TaskExecutorRepeatTemplate().setThrottleLimit(-1)); - } - } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/SystemPropertyInitializerTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/SystemPropertyInitializerTests.java deleted file mode 100644 index f35d70785..000000000 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/SystemPropertyInitializerTests.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2006-2022 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.support; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -/** - * @author Dave Syer - * - */ -class SystemPropertyInitializerTests { - - private static final String SIMPLE_NAME = SystemPropertyInitializerTests.class.getSimpleName(); - - private final SystemPropertyInitializer initializer = new SystemPropertyInitializer(); - - @BeforeEach - @AfterEach - void initializeProperty() { - System.clearProperty(SystemPropertyInitializer.ENVIRONMENT); - System.clearProperty(SIMPLE_NAME); - } - - @Test - void testSetKeyName() throws Exception { - initializer.setKeyName(SIMPLE_NAME); - System.setProperty(SIMPLE_NAME, "foo"); - initializer.afterPropertiesSet(); - assertEquals("foo", System.getProperty(SIMPLE_NAME)); - } - - @Test - void testSetDefaultValue() throws Exception { - initializer.setDefaultValue("foo"); - initializer.afterPropertiesSet(); - assertEquals("foo", System.getProperty(SystemPropertyInitializer.ENVIRONMENT)); - } - - @Test - void testNoDefaultValue() { - assertThrows(IllegalStateException.class, initializer::afterPropertiesSet); - } - -} diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/chunk/RemoteChunkingManagerStepBuilder.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/chunk/RemoteChunkingManagerStepBuilder.java index 4d033b61c..dce57ad57 100644 --- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/chunk/RemoteChunkingManagerStepBuilder.java +++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/chunk/RemoteChunkingManagerStepBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2023 the original author or authors. + * Copyright 2019-2025 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. @@ -82,17 +82,6 @@ public class RemoteChunkingManagerStepBuilder extends FaultTolerantStepBui private long throttleLimit = DEFAULT_THROTTLE_LIMIT; - /** - * Create a new {@link RemoteChunkingManagerStepBuilder}. - * @param stepName name of the manager step - * @deprecated use - * {@link RemoteChunkingManagerStepBuilder#RemoteChunkingManagerStepBuilder(String, JobRepository)} - */ - @Deprecated(since = "5.0", forRemoval = true) - public RemoteChunkingManagerStepBuilder(String stepName) { - super(new StepBuilder(stepName)); - } - /** * Create a new {@link RemoteChunkingManagerStepBuilder}. * @param stepName name of the manager step @@ -228,21 +217,6 @@ public class RemoteChunkingManagerStepBuilder extends FaultTolerantStepBui return this; } - /** - * Set the job repository - * @param jobRepository the repository to set - * @return this to enable fluent chaining - * @deprecated use - * {@link RemoteChunkingManagerStepBuilder#RemoteChunkingManagerStepBuilder(String, JobRepository)} - */ - @Override - @SuppressWarnings("removal") - @Deprecated(since = "5.1", forRemoval = true) - public RemoteChunkingManagerStepBuilder repository(JobRepository jobRepository) { - super.repository(jobRepository); - return this; - } - @Override public RemoteChunkingManagerStepBuilder transactionManager(PlatformTransactionManager transactionManager) { super.transactionManager(transactionManager); diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningManagerStepBuilder.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningManagerStepBuilder.java index 9759b4bc1..fd9a24f66 100644 --- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningManagerStepBuilder.java +++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningManagerStepBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2023 the original author or authors. + * Copyright 2019-2025 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. @@ -78,17 +78,6 @@ public class RemotePartitioningManagerStepBuilder extends PartitionStepBuilder { private long timeout = DEFAULT_TIMEOUT; - /** - * Create a new {@link RemotePartitioningManagerStepBuilder}. - * @param stepName name of the manager step - * @deprecated use - * {@link RemotePartitioningManagerStepBuilder#RemotePartitioningManagerStepBuilder(String, JobRepository)} - */ - @Deprecated(since = "5.0", forRemoval = true) - public RemotePartitioningManagerStepBuilder(String stepName) { - super(new StepBuilder(stepName)); - } - /** * Create a new {@link RemotePartitioningManagerStepBuilder}. * @param stepName name of the manager step @@ -243,21 +232,6 @@ public class RemotePartitioningManagerStepBuilder extends PartitionStepBuilder { return this.inputChannel == null; } - /** - * Set the job repository - * @param jobRepository the repository to set - * @return this to enable fluent chaining - * @deprecated use - * {@link RemotePartitioningManagerStepBuilder#RemotePartitioningManagerStepBuilder(String, JobRepository)} - */ - @Override - @SuppressWarnings("removal") - @Deprecated(since = "5.1", forRemoval = true) - public RemotePartitioningManagerStepBuilder repository(JobRepository jobRepository) { - super.repository(jobRepository); - return this; - } - @Override public RemotePartitioningManagerStepBuilder partitioner(String workerStepName, Partitioner partitioner) { super.partitioner(workerStepName, partitioner); diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningWorkerStepBuilder.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningWorkerStepBuilder.java index 16fda8232..a0fa3b9f1 100644 --- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningWorkerStepBuilder.java +++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningWorkerStepBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 the original author or authors. + * Copyright 2018-2025 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. @@ -80,17 +80,6 @@ public class RemotePartitioningWorkerStepBuilder extends StepBuilder { private BeanFactory beanFactory; - /** - * Initialize a step builder for a step with the given name. - * @param name the name of the step - * @deprecated use - * {@link RemotePartitioningWorkerStepBuilder#RemotePartitioningWorkerStepBuilder(String, JobRepository)} - */ - @Deprecated(since = "5.0", forRemoval = true) - public RemotePartitioningWorkerStepBuilder(String name) { - super(name); - } - /** * Initialize a step builder for a step with the given name. * @param name the name of the step @@ -157,21 +146,6 @@ public class RemotePartitioningWorkerStepBuilder extends StepBuilder { return this; } - /** - * Set the job repository - * @param jobRepository the repository to set - * @return this to enable fluent chaining - * @deprecated use - * {@link RemotePartitioningWorkerStepBuilder#RemotePartitioningWorkerStepBuilder(String, JobRepository)} - */ - @Override - @SuppressWarnings("removal") - @Deprecated(since = "5.1", forRemoval = true) - public RemotePartitioningWorkerStepBuilder repository(JobRepository jobRepository) { - super.repository(jobRepository); - return this; - } - @Override public RemotePartitioningWorkerStepBuilder startLimit(int startLimit) { super.startLimit(startLimit); @@ -196,39 +170,18 @@ public class RemotePartitioningWorkerStepBuilder extends StepBuilder { return this; } - @Deprecated(since = "5.0", forRemoval = true) - @Override - public TaskletStepBuilder tasklet(Tasklet tasklet) { - configureWorkerIntegrationFlow(); - return super.tasklet(tasklet); - } - @Override public TaskletStepBuilder tasklet(Tasklet tasklet, PlatformTransactionManager transactionManager) { configureWorkerIntegrationFlow(); return super.tasklet(tasklet, transactionManager); } - @Deprecated(since = "5.0", forRemoval = true) - @Override - public SimpleStepBuilder chunk(int chunkSize) { - configureWorkerIntegrationFlow(); - return super.chunk(chunkSize); - } - @Override public SimpleStepBuilder chunk(int chunkSize, PlatformTransactionManager transactionManager) { configureWorkerIntegrationFlow(); return super.chunk(chunkSize, transactionManager); } - @Deprecated(since = "5.0", forRemoval = true) - @Override - public SimpleStepBuilder chunk(CompletionPolicy completionPolicy) { - configureWorkerIntegrationFlow(); - return super.chunk(completionPolicy); - } - @Override public SimpleStepBuilder chunk(CompletionPolicy completionPolicy, PlatformTransactionManager transactionManager) { diff --git a/spring-batch-samples/README.md b/spring-batch-samples/README.md index 770c7fd93..4b334cf8e 100644 --- a/spring-batch-samples/README.md +++ b/spring-batch-samples/README.md @@ -603,7 +603,7 @@ class without any argument to start the sample. ### MongoDB sample This sample is a showcase of MongoDB support in Spring Batch. It copies data from -an input collection to an output collection using `MongoItemReader` and `MongoItemWriter`. +an input collection to an output collection using `MongoPagingItemReader` and `MongoItemWriter`. To run the sample, you need to have a MongoDB server up and running on `localhost:27017` (you can change these defaults in `mongodb-sample.properties`). If you use docker, diff --git a/spring-batch-samples/src/main/resources/data-source-context.xml b/spring-batch-samples/src/main/resources/data-source-context.xml index 39c1506bd..8f17365d1 100644 --- a/spring-batch-samples/src/main/resources/data-source-context.xml +++ b/spring-batch-samples/src/main/resources/data-source-context.xml @@ -25,5 +25,4 @@ - diff --git a/spring-batch-samples/src/main/resources/org/springframework/batch/samples/misc/jmx/adhoc-job-launcher-context.xml b/spring-batch-samples/src/main/resources/org/springframework/batch/samples/misc/jmx/adhoc-job-launcher-context.xml index efbc83b8d..a94273a43 100644 --- a/spring-batch-samples/src/main/resources/org/springframework/batch/samples/misc/jmx/adhoc-job-launcher-context.xml +++ b/spring-batch-samples/src/main/resources/org/springframework/batch/samples/misc/jmx/adhoc-job-launcher-context.xml @@ -11,13 +11,13 @@ - + + p:dataSource-ref="dataSource" p:transactionManager-ref="transactionManager"/> - + + p:dataSource-ref="dataSource" p:transactionManager-ref="transactionManager"/>