@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
* <li>a {@link JobLauncher} named "jobLauncher"</li>
|
||||
* <li>a {@link JobRegistry} named "jobRegistry"</li>
|
||||
* <li>a {@link JobOperator} named "JobOperator"</li>
|
||||
* <li>a {@link JobRegistryBeanPostProcessor} named "jobRegistryBeanPostProcessor"</li>
|
||||
* <li>a {@link JobRegistrySmartInitializingSingleton} named
|
||||
* "jobRegistrySmartInitializingSingleton"</li>
|
||||
* <li>a {@link org.springframework.batch.core.scope.StepScope} named "stepScope"</li>
|
||||
* <li>a {@link org.springframework.batch.core.scope.JobScope} named "jobScope"</li>
|
||||
* </ul>
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
* <p>
|
||||
* 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<String> 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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.
|
||||
* <p>
|
||||
* 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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<I, O> implements FactoryBean<Step>, BeanN
|
||||
|
||||
private TaskExecutor taskExecutor;
|
||||
|
||||
private Integer throttleLimit;
|
||||
|
||||
private ItemReader<? extends I> itemReader;
|
||||
|
||||
private ItemProcessor<? super I, ? extends O> itemProcessor;
|
||||
@@ -473,9 +471,6 @@ public class StepParserStepFactoryBean<I, O> implements FactoryBean<Step>, 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<I, O> implements FactoryBean<Step>, 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.
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<JobBuilder> {
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
||||
@@ -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<B extends JobBuilderHelper<B>> {
|
||||
|
||||
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<B extends JobBuilderHelper<B>> {
|
||||
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)
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<T, S> implements SkipListener<T, S> {
|
||||
|
||||
@Override
|
||||
public void onSkipInRead(Throwable t) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSkipInWrite(S item, Throwable t) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSkipInProcess(T item, Throwable t) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<B extends AbstractTaskletStepBu
|
||||
|
||||
private ExceptionHandler exceptionHandler = new DefaultExceptionHandler();
|
||||
|
||||
private int throttleLimit = TaskExecutorRepeatTemplate.DEFAULT_THROTTLE_LIMIT;
|
||||
|
||||
private TaskExecutor taskExecutor;
|
||||
|
||||
public AbstractTaskletStepBuilder(StepBuilderHelper<?> parent) {
|
||||
@@ -88,7 +86,6 @@ public abstract class AbstractTaskletStepBuilder<B extends AbstractTaskletStepBu
|
||||
this.transactionAttribute = parent.transactionAttribute;
|
||||
this.streams.addAll(parent.streams);
|
||||
this.exceptionHandler = parent.exceptionHandler;
|
||||
this.throttleLimit = parent.throttleLimit;
|
||||
this.taskExecutor = parent.taskExecutor;
|
||||
}
|
||||
|
||||
@@ -125,7 +122,6 @@ public abstract class AbstractTaskletStepBuilder<B extends AbstractTaskletStepBu
|
||||
if (taskExecutor != null) {
|
||||
TaskExecutorRepeatTemplate repeatTemplate = new TaskExecutorRepeatTemplate();
|
||||
repeatTemplate.setTaskExecutor(taskExecutor);
|
||||
repeatTemplate.setThrottleLimit(throttleLimit);
|
||||
stepOperations = repeatTemplate;
|
||||
}
|
||||
|
||||
@@ -210,24 +206,6 @@ public abstract class AbstractTaskletStepBuilder<B extends AbstractTaskletStepBu
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* In the case of an asynchronous {@link #taskExecutor(TaskExecutor)} the number of
|
||||
* concurrent tasklet executions can be throttled (beyond any throttling provided by a
|
||||
* thread pool). The throttle limit should be less than the data source pool size used
|
||||
* in the job repository for this step.
|
||||
* @param throttleLimit maximum number of concurrent tasklet executions allowed
|
||||
* @return this for fluent chaining
|
||||
* @deprecated with no replacement since 5.0, scheduled for removal in 6.0. Use a
|
||||
* custom {@link RepeatOperations} implementation (based on a {@link TaskExecutor}
|
||||
* with a bounded task queue) and set it on the step with
|
||||
* {@link #stepOperations(RepeatOperations)}.
|
||||
*/
|
||||
@Deprecated(since = "5.0", forRemoval = true)
|
||||
public B throttleLimit(int throttleLimit) {
|
||||
this.throttleLimit = throttleLimit;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the exception handler to use in the case of tasklet failures. Default is to
|
||||
* rethrow everything.
|
||||
@@ -302,11 +280,6 @@ public abstract class AbstractTaskletStepBuilder<B extends AbstractTaskletStepBu
|
||||
return taskExecutor;
|
||||
}
|
||||
|
||||
@Deprecated(since = "5.0", forRemoval = true)
|
||||
protected int getThrottleLimit() {
|
||||
return throttleLimit;
|
||||
}
|
||||
|
||||
protected TransactionAttribute getTransactionAttribute() {
|
||||
return transactionAttribute;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -34,16 +34,6 @@ import org.springframework.transaction.PlatformTransactionManager;
|
||||
*/
|
||||
public class StepBuilder extends StepBuilderHelper<StepBuilder> {
|
||||
|
||||
/**
|
||||
* 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<StepBuilder> {
|
||||
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<StepBuilder> {
|
||||
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.
|
||||
*
|
||||
* <pre>
|
||||
* new StepBuilder("step1").<Order, Ledger> chunk(100).reader(new OrderReader()).writer(new LedgerWriter())
|
||||
* // ... etc.
|
||||
* </pre>
|
||||
* @param chunkSize the chunk size (commit interval)
|
||||
* @return a {@link SimpleStepBuilder}
|
||||
* @param <I> the type of item to be processed as input
|
||||
* @param <O> the type of item to be output
|
||||
* @deprecated use {@link StepBuilder#chunk(int, PlatformTransactionManager)}
|
||||
*/
|
||||
@Deprecated(since = "5.0", forRemoval = true)
|
||||
public <I, O> SimpleStepBuilder<I, O> chunk(int chunkSize) {
|
||||
return new SimpleStepBuilder<I, O>(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<StepBuilder> {
|
||||
return new SimpleStepBuilder<I, O>(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.
|
||||
*
|
||||
* <pre>
|
||||
* new StepBuilder("step1").<Order, Ledger> chunk(100).reader(new OrderReader()).writer(new LedgerWriter())
|
||||
* // ... etc.
|
||||
* </pre>
|
||||
* @param completionPolicy the completion policy to use to control chunk processing
|
||||
* @return a {@link SimpleStepBuilder}
|
||||
* @param <I> the type of item to be processed as input
|
||||
* @param <O> the type of item to be output
|
||||
* @deprecated use
|
||||
* {@link StepBuilder#chunk(CompletionPolicy, PlatformTransactionManager)}
|
||||
*/
|
||||
@Deprecated(since = "5.0", forRemoval = true)
|
||||
public <I, O> SimpleStepBuilder<I, O> chunk(CompletionPolicy completionPolicy) {
|
||||
return new SimpleStepBuilder<I, O>(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
|
||||
|
||||
@@ -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<B extends StepBuilderHelper<B>> {
|
||||
|
||||
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<B extends StepBuilderHelper<B>> {
|
||||
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)
|
||||
|
||||
@@ -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<TaskletStepBu
|
||||
super(parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tasklet the tasklet to use
|
||||
* @return this for fluent chaining
|
||||
* @deprecated use
|
||||
* {@link TaskletStepBuilder#tasklet(Tasklet, PlatformTransactionManager)}
|
||||
*/
|
||||
@Deprecated(since = "5.0", forRemoval = true)
|
||||
public TaskletStepBuilder tasklet(Tasklet tasklet) {
|
||||
this.tasklet = tasklet;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tasklet the tasklet to use
|
||||
* @return this for fluent chaining
|
||||
|
||||
@@ -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.
|
||||
@@ -441,20 +441,6 @@ public class SimpleStepFactoryBean<T, S> implements FactoryBean<Step>, 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<T, S> builder) {
|
||||
|
||||
builder.reader(itemReader);
|
||||
@@ -482,7 +468,6 @@ public class SimpleStepFactoryBean<T, S> implements FactoryBean<Step>, 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<T, S> implements FactoryBean<Step>, BeanNameA
|
||||
builder.chunkOperations(chunkOperations);
|
||||
builder.stepOperations(stepOperations);
|
||||
builder.taskExecutor(taskExecutor);
|
||||
builder.throttleLimit(throttleLimit);
|
||||
builder.exceptionHandler(exceptionHandler);
|
||||
if (isReaderTransactionalQueue) {
|
||||
builder.readerIsTransactionalQueue();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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">
|
||||
|
||||
<xsd:import namespace="http://www.springframework.org/schema/beans" />
|
||||
<xsd:import namespace="http://www.springframework.org/schema/tool" />
|
||||
@@ -265,20 +265,6 @@
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="lob-handler" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A reference to the lob handler (optional). Only override if using Oracle and
|
||||
the database type is not being detected for some reason.
|
||||
This attribute is deprecated Since 5.2 with no replacement. Scheduled for removal in v6.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.jdbc.support.lob.LobHandler" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="conversion-service" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
@@ -680,16 +666,6 @@
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="throttle-limit" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
This limits the number of tasks queued for concurrent
|
||||
processing to prevent thread pools from being overwhelmed.
|
||||
Default is 4. This is deprecated in favor of using similar
|
||||
features in TaskExecutor implementations.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attributeGroup ref="allowStartIfCompleteAttribute"/>
|
||||
</xsd:complexType>
|
||||
|
||||
|
||||
@@ -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<String> 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"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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"));
|
||||
|
||||
@@ -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<Object, Object> 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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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<String, String> factory = getStepFactory("foo", "bar");
|
||||
factory.setTaskExecutor(new SimpleAsyncTaskExecutor());
|
||||
factory.setThrottleLimit(1);
|
||||
|
||||
AbstractStep step = (AbstractStep) factory.getObject();
|
||||
step.setName("step1");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
<bean id="jobRegistry" class="org.springframework.batch.core.configuration.support.MapJobRegistry"/>
|
||||
|
||||
<bean class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
|
||||
<bean class="org.springframework.batch.core.configuration.support.JobRegistrySmartInitializingSingleton">
|
||||
<property name="jobRegistry" ref="jobRegistry"/>
|
||||
</bean>
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
http://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx.xsd">
|
||||
|
||||
<bean
|
||||
class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
|
||||
class="org.springframework.batch.core.configuration.support.JobRegistrySmartInitializingSingleton">
|
||||
<property name="jobRegistry" ref="registry" />
|
||||
</bean>
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
|
||||
<bean class="org.springframework.batch.core.configuration.support.JobRegistrySmartInitializingSingleton">
|
||||
<property name="jobRegistry" ref="jobRegistry" />
|
||||
</bean>
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<bean id="jobRegistry"
|
||||
class="org.springframework.batch.core.configuration.support.MapJobRegistry" />
|
||||
<bean
|
||||
class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
|
||||
class="org.springframework.batch.core.configuration.support.JobRegistrySmartInitializingSingleton">
|
||||
<property name="jobRegistry" ref="jobRegistry" />
|
||||
</bean>
|
||||
|
||||
|
||||
@@ -14,9 +14,8 @@
|
||||
<beans:bean id="transactionManager" class="org.springframework.jdbc.support.JdbcTransactionManager">
|
||||
<beans:property name="dataSource" ref="dataSource"/>
|
||||
</beans:bean>
|
||||
<beans:bean id="lobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler"/>
|
||||
<beans:bean id="serializer" class="org.springframework.batch.core.repository.dao.DefaultExecutionContextSerializer"/>
|
||||
|
||||
<job-repository id="jobRepo1" data-source="dataSource" jdbc-operations="jdbcTemplate" transaction-manager="transactionManager" lob-handler="lobHandler" max-varchar-length="100" serializer="serializer"/>
|
||||
<job-repository id="jobRepo1" data-source="dataSource" jdbc-operations="jdbcTemplate" transaction-manager="transactionManager" max-varchar-length="100" serializer="serializer"/>
|
||||
|
||||
</beans:beans>
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
<job id="job">
|
||||
<step id="step">
|
||||
<tasklet start-limit="25" allow-start-if-complete="true" task-executor="taskExecutor" throttle-limit="10">
|
||||
<tasklet start-limit="25" allow-start-if-complete="true" task-executor="taskExecutor">
|
||||
<chunk reader="reader" processor="processor" writer="writer" commit-interval="10" skip-limit="20"
|
||||
retry-limit="3" cache-capacity="100" reader-transactional-queue="true">
|
||||
<retry-listeners>
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
<bean id="jobRegistry" class="org.springframework.batch.core.configuration.support.MapJobRegistry"/>
|
||||
|
||||
<bean class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
|
||||
<bean class="org.springframework.batch.core.configuration.support.JobRegistrySmartInitializingSingleton">
|
||||
<property name="jobRegistry" ref="jobRegistry"/>
|
||||
</bean>
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
<bean id="jobRegistry" class="org.springframework.batch.core.configuration.support.MapJobRegistry"/>
|
||||
|
||||
<bean class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
|
||||
<bean class="org.springframework.batch.core.configuration.support.JobRegistrySmartInitializingSingleton">
|
||||
<property name="jobRegistry" ref="jobRegistry"/>
|
||||
</bean>
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
<import resource="test-environment-with-registry.xml" />
|
||||
|
||||
<bean class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
|
||||
<bean class="org.springframework.batch.core.configuration.support.JobRegistrySmartInitializingSingleton">
|
||||
<property name="jobRegistry" ref="jobRegistry"/>
|
||||
</bean>
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<property name="jobRepository" ref="jobRepository" />
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
|
||||
<bean class="org.springframework.batch.core.configuration.support.JobRegistrySmartInitializingSingleton">
|
||||
<property name="jobRegistry" ref="jobRegistry"/>
|
||||
</bean>
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]
|
||||
----
|
||||
<bean id="jobRegistryBeanPostProcessor" class="org.spr...JobRegistryBeanPostProcessor">
|
||||
<property name="jobRegistry" ref="jobRegistry"/>
|
||||
</bean>
|
||||
----
|
||||
|
||||
====
|
||||
|
||||
|
||||
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
.<String, String>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
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Restartable {@link ItemReader} that reads documents from MongoDB via a paging
|
||||
* technique.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If you set JSON String query {@link #setQuery(String)} then it executes the JSON to
|
||||
* retrieve the requested documents.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If you set Query object {@link #setQuery(Query)} then it executes the Query to retrieve
|
||||
* the requested documents.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* 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.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The JSON String query provided supports parameter substitution via ?<index>
|
||||
* placeholders where the <index> indicates the index of the parameterValue to
|
||||
* substitute.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The implementation is thread-safe between calls to {@link #open(ExecutionContext)}, but
|
||||
* remember to use <code>saveState=false</code> if used in a multi-threaded client (no
|
||||
* restart available).
|
||||
* </p>
|
||||
*
|
||||
* @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<T> extends AbstractPaginatedDataItemReader<T> implements InitializingBean {
|
||||
|
||||
protected MongoOperations template;
|
||||
|
||||
protected Query query;
|
||||
|
||||
protected String queryString;
|
||||
|
||||
protected Class<? extends T> type;
|
||||
|
||||
protected Sort sort;
|
||||
|
||||
protected String hint;
|
||||
|
||||
protected String fields;
|
||||
|
||||
protected String collection;
|
||||
|
||||
protected List<Object> 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<? extends T> 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<Object> 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<String, Sort.Direction> 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<T> 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<T>) template.find(mongoQuery, type, collection).iterator();
|
||||
}
|
||||
else {
|
||||
return (Iterator<T>) template.find(mongoQuery, type).iterator();
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
Pageable pageRequest = PageRequest.of(page, pageSize);
|
||||
query.with(pageRequest);
|
||||
|
||||
if (StringUtils.hasText(collection)) {
|
||||
return (Iterator<T>) template.find(query, type, collection).iterator();
|
||||
}
|
||||
else {
|
||||
return (Iterator<T>) 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<Object> 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<String, Sort.Direction> sorts) {
|
||||
List<Sort.Order> sortValues = new ArrayList<>(sorts.size());
|
||||
|
||||
for (Map.Entry<String, Sort.Direction> curSort : sorts.entrySet()) {
|
||||
sortValues.add(new Sort.Order(curSort.getValue(), curSort.getKey()));
|
||||
}
|
||||
|
||||
return Sort.by(sortValues);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<T> implements ItemWriter<T>, 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}.
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -67,78 +78,186 @@ import org.springframework.util.ClassUtils;
|
||||
* @author Mahmoud Ben Hassine
|
||||
* @author Parikshit Dutta
|
||||
*/
|
||||
public class MongoPagingItemReader<T> extends MongoItemReader<T> {
|
||||
public class MongoPagingItemReader<T> extends AbstractPaginatedDataItemReader<T> implements InitializingBean {
|
||||
|
||||
protected MongoOperations template;
|
||||
|
||||
protected Query query;
|
||||
|
||||
protected String queryString;
|
||||
|
||||
protected Class<? extends T> type;
|
||||
|
||||
protected Sort sort;
|
||||
|
||||
protected String hint;
|
||||
|
||||
protected String fields;
|
||||
|
||||
protected String collection;
|
||||
|
||||
protected List<Object> 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<? extends T> 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<Object> 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<String, Sort.Direction> 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<T> 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<T>) template.find(mongoQuery, type, collection).iterator();
|
||||
}
|
||||
else {
|
||||
return (Iterator<T>) template.find(mongoQuery, type).iterator();
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
Pageable pageRequest = PageRequest.of(page, pageSize);
|
||||
query.with(pageRequest);
|
||||
|
||||
if (StringUtils.hasText(collection)) {
|
||||
return (Iterator<T>) template.find(query, type, collection).iterator();
|
||||
}
|
||||
else {
|
||||
return (Iterator<T>) 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<T> doPageRead() {
|
||||
return super.doPageRead();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String replacePlaceholders(String input, List<Object> 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<String, Sort.Direction> sorts) {
|
||||
return super.convertToSort(sorts);
|
||||
List<Sort.Order> sortValues = new ArrayList<>(sorts.size());
|
||||
|
||||
for (Map.Entry<String, Sort.Direction> curSort : sorts.entrySet()) {
|
||||
sortValues.add(new Sort.Order(curSort.getValue(), curSort.getKey()));
|
||||
}
|
||||
|
||||
return Sort.by(sortValues);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Restartable {@link ItemReader} that reads objects from the graph database Neo4j via a
|
||||
* paging technique.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* 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.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* 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.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* This implementation is thread-safe between calls to
|
||||
* {@link #open(org.springframework.batch.item.ExecutionContext)}, however you should set
|
||||
* <code>saveState=false</code> if used in a multi-threaded environment (no restart
|
||||
* available).
|
||||
* </p>
|
||||
*
|
||||
* @author Michael Minella
|
||||
* @author Mahmoud Ben Hassine
|
||||
* @deprecated since 5.0 in favor of the item reader from <a href=
|
||||
* "https://github.com/spring-projects/spring-batch-extensions/blob/main/spring-batch-neo4j">...</a>
|
||||
*/
|
||||
@Deprecated
|
||||
public class Neo4jItemReader<T> extends AbstractPaginatedDataItemReader<T> 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<T> targetType;
|
||||
|
||||
private Map<String, Object> 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<String, Object> parameterValues) {
|
||||
this.parameterValues = parameterValues;
|
||||
}
|
||||
|
||||
protected final Map<String, Object> getParameterValues() {
|
||||
return this.parameterValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* The start segment of the cypher query. START is prepended to the statement provided
|
||||
* and should <em>not</em> 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 <em>not</em> 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 <em>not</em> 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 <em>not</em> 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 <em>not</em> 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<T> targetType) {
|
||||
this.targetType = targetType;
|
||||
}
|
||||
|
||||
protected final Class<T> 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<T> doPageRead() {
|
||||
Session session = getSessionFactory().openSession();
|
||||
|
||||
Iterable<T> queryResults = session.query(getTargetType(), generateLimitCypherQuery(), getParameterValues());
|
||||
|
||||
if (queryResults != null) {
|
||||
return queryResults.iterator();
|
||||
}
|
||||
else {
|
||||
return new ArrayList<T>().iterator();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* A {@link ItemWriter} implementation that writes to a Neo4j database.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* This writer is thread-safe once all properties are set (normal singleton behavior) so
|
||||
* it can be used in multiple concurrent transactions.
|
||||
* </p>
|
||||
*
|
||||
* @author Michael Minella
|
||||
* @author Glenn Renfro
|
||||
* @author Mahmoud Ben Hassine
|
||||
* @deprecated since 5.0 in favor of the item writer from <a href=
|
||||
* "https://github.com/spring-projects/spring-batch-extensions/blob/main/spring-batch-neo4j">...</a>
|
||||
*
|
||||
*/
|
||||
@Deprecated
|
||||
public class Neo4jItemWriter<T> implements ItemWriter<T>, 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<? extends T> 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<? extends T> items) {
|
||||
if (delete) {
|
||||
delete(items);
|
||||
}
|
||||
else {
|
||||
save(items);
|
||||
}
|
||||
}
|
||||
|
||||
private void delete(Chunk<? extends T> items) {
|
||||
Session session = this.sessionFactory.openSession();
|
||||
|
||||
for (T item : items) {
|
||||
session.delete(item);
|
||||
}
|
||||
}
|
||||
|
||||
private void save(Chunk<? extends T> items) {
|
||||
Session session = this.sessionFactory.openSession();
|
||||
|
||||
for (T item : items) {
|
||||
session.save(item);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<T> {
|
||||
|
||||
protected MongoOperations template;
|
||||
|
||||
protected String jsonQuery;
|
||||
|
||||
protected Class<? extends T> targetType;
|
||||
|
||||
protected Map<String, Sort.Direction> sorts;
|
||||
|
||||
protected String hint;
|
||||
|
||||
protected String fields;
|
||||
|
||||
protected String collection;
|
||||
|
||||
protected List<Object> 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<T> 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<T> 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<T> 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<T> 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<T> 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<T> 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<T> targetType(Class<? extends T> 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<T> parameterValues(List<Object> 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<T> 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<T> 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<T> sorts(Map<String, Sort.Direction> 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<T> 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<T> 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<T> 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<T> query(Query query) {
|
||||
this.query = query;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates and builds a {@link MongoItemReader}.
|
||||
* @return a {@link MongoItemReader}
|
||||
*/
|
||||
public MongoItemReader<T> 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<T> 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<T> {
|
||||
|
||||
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<T> 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}.
|
||||
|
||||
@@ -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<T> extends MongoItemReaderBuilder<T> {
|
||||
public class MongoPagingItemReaderBuilder<T> {
|
||||
|
||||
protected MongoOperations template;
|
||||
|
||||
protected String jsonQuery;
|
||||
|
||||
protected Class<? extends T> targetType;
|
||||
|
||||
protected Map<String, Sort.Direction> sorts;
|
||||
|
||||
protected String hint;
|
||||
|
||||
protected String fields;
|
||||
|
||||
protected String collection;
|
||||
|
||||
protected List<Object> 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<T> extends MongoItemReaderBuilder<T> {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MongoPagingItemReader<T> build() {
|
||||
Assert.notNull(this.template, "template is required.");
|
||||
if (this.saveState) {
|
||||
|
||||
@@ -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 <a href=
|
||||
* "https://github.com/spring-projects/spring-batch-extensions/blob/main/spring-batch-neo4j">...</a>
|
||||
*/
|
||||
@Deprecated
|
||||
public class Neo4jItemReaderBuilder<T> {
|
||||
|
||||
private SessionFactory sessionFactory;
|
||||
|
||||
private String startStatement;
|
||||
|
||||
private String returnStatement;
|
||||
|
||||
private String matchStatement;
|
||||
|
||||
private String whereStatement;
|
||||
|
||||
private String orderByStatement;
|
||||
|
||||
private Class<T> targetType;
|
||||
|
||||
private Map<String, Object> 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<T> 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<T> 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<T> 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<T> 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<T> 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<T> 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<T> parameterValues(Map<String, Object> parameterValues) {
|
||||
this.parameterValues = parameterValues;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The start segment of the cypher query. START is prepended to the statement provided
|
||||
* and should <em>not</em> be included.
|
||||
* @param startStatement the start fragment of the cypher query.
|
||||
* @return this instance for method chaining
|
||||
* @see Neo4jItemReader#setStartStatement(String)
|
||||
*/
|
||||
public Neo4jItemReaderBuilder<T> startStatement(String startStatement) {
|
||||
this.startStatement = startStatement;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The return statement of the cypher query. RETURN is prepended to the statement
|
||||
* provided and should <em>not</em> be included
|
||||
* @param returnStatement the return fragment of the cypher query.
|
||||
* @return this instance for method chaining
|
||||
* @see Neo4jItemReader#setReturnStatement(String)
|
||||
*/
|
||||
public Neo4jItemReaderBuilder<T> 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 <em>not</em> be included.
|
||||
* @param matchStatement the match fragment of the cypher query
|
||||
* @return this instance for method chaining
|
||||
* @see Neo4jItemReader#setMatchStatement(String)
|
||||
*/
|
||||
public Neo4jItemReaderBuilder<T> 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 <em>not</em> be included.
|
||||
* @param whereStatement where fragment of the cypher query
|
||||
* @return this instance for method chaining
|
||||
* @see Neo4jItemReader#setWhereStatement(String)
|
||||
*/
|
||||
public Neo4jItemReaderBuilder<T> 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 <em>not</em> be included.
|
||||
* @param orderByStatement order by fragment of the cypher query.
|
||||
* @return this instance for method chaining
|
||||
* @see Neo4jItemReader#setOrderByStatement(String)
|
||||
*/
|
||||
public Neo4jItemReaderBuilder<T> 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<T> targetType(Class<T> targetType) {
|
||||
this.targetType = targetType;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a fully constructed {@link Neo4jItemReader}.
|
||||
* @return a new {@link Neo4jItemReader}
|
||||
*/
|
||||
public Neo4jItemReader<T> 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<T> 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 <a href=
|
||||
* "https://github.com/spring-projects/spring-batch-extensions/blob/main/spring-batch-neo4j">...</a>
|
||||
*/
|
||||
@Deprecated
|
||||
public class Neo4jItemWriterBuilder<T> {
|
||||
|
||||
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<T> 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<T> 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<T> build() {
|
||||
Assert.notNull(sessionFactory, "sessionFactory is required.");
|
||||
Neo4jItemWriter<T> writer = new Neo4jItemWriter<>();
|
||||
writer.setDelete(this.delete);
|
||||
writer.setSessionFactory(this.sessionFactory);
|
||||
return writer;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<Object> 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<Object> 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<Object> 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<Object> items = Chunk.of(new Item(1), new Item(2));
|
||||
|
||||
writer.setCollection("collection");
|
||||
|
||||
@@ -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<String> result;
|
||||
|
||||
@Mock
|
||||
private SessionFactory sessionFactory;
|
||||
|
||||
@Mock
|
||||
private Session session;
|
||||
|
||||
private Neo4jItemReader<String> buildSessionBasedReader() throws Exception {
|
||||
Neo4jItemReader<String> 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<String> 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<String> itemReader = buildSessionBasedReader();
|
||||
|
||||
ArgumentCaptor<String> 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<String> itemReader = buildSessionBasedReader();
|
||||
ArgumentCaptor<String> 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<String> 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<String> itemReader = buildSessionBasedReader();
|
||||
Map<String, Object> 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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<String> 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<String> 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<String> 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");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<Item> writer = new MongoItemWriterBuilder<Item>().template(this.template).delete(true).build();
|
||||
MongoItemWriter<Item> writer = new MongoItemWriterBuilder<Item>().template(this.template)
|
||||
.mode(MongoItemWriter.Mode.REMOVE)
|
||||
.build();
|
||||
|
||||
writer.write(this.removeItems);
|
||||
|
||||
|
||||
@@ -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<String> result;
|
||||
|
||||
@Mock
|
||||
private SessionFactory sessionFactory;
|
||||
|
||||
@Mock
|
||||
private Session session;
|
||||
|
||||
@Test
|
||||
void testFullyQualifiedItemReader() throws Exception {
|
||||
Neo4jItemReader<String> itemReader = new Neo4jItemReaderBuilder<String>().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<String> itemReader = new Neo4jItemReaderBuilder<String>().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<String, Object> params = new HashMap<>();
|
||||
params.put("foo", "bar");
|
||||
Neo4jItemReader<String> itemReader = new Neo4jItemReaderBuilder<String>().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<String>().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<String>().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<String>().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<String>().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<String>().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<String>().sessionFactory(this.sessionFactory)
|
||||
.targetType(String.class)
|
||||
.startStatement("n=node(*)")
|
||||
.returnStatement("*")
|
||||
.orderByStatement("n.age")
|
||||
.saveState(false)
|
||||
.pageSize(50)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNullTargetType() {
|
||||
validateExceptionMessage(new Neo4jItemReaderBuilder<String>().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<String>().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<String>().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<String>().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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<String> writer = new Neo4jItemWriterBuilder<String>().sessionFactory(this.sessionFactory)
|
||||
.build();
|
||||
Chunk<String> 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<String> writer = new Neo4jItemWriterBuilder<String>().delete(true)
|
||||
.sessionFactory(this.sessionFactory)
|
||||
.build();
|
||||
Chunk<String> 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<String>().build());
|
||||
assertEquals("sessionFactory is required.", exception.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<String> threadNames = ConcurrentHashMap.newKeySet();
|
||||
|
||||
@@ -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() {
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<I, O> 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<I, O> 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<I, O> repository(JobRepository jobRepository) {
|
||||
super.repository(jobRepository);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RemoteChunkingManagerStepBuilder<I, O> transactionManager(PlatformTransactionManager transactionManager) {
|
||||
super.transactionManager(transactionManager);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 <I, O> SimpleStepBuilder<I, O> chunk(int chunkSize) {
|
||||
configureWorkerIntegrationFlow();
|
||||
return super.chunk(chunkSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <I, O> SimpleStepBuilder<I, O> chunk(int chunkSize, PlatformTransactionManager transactionManager) {
|
||||
configureWorkerIntegrationFlow();
|
||||
return super.chunk(chunkSize, transactionManager);
|
||||
}
|
||||
|
||||
@Deprecated(since = "5.0", forRemoval = true)
|
||||
@Override
|
||||
public <I, O> SimpleStepBuilder<I, O> chunk(CompletionPolicy completionPolicy) {
|
||||
configureWorkerIntegrationFlow();
|
||||
return super.chunk(completionPolicy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <I, O> SimpleStepBuilder<I, O> chunk(CompletionPolicy completionPolicy,
|
||||
PlatformTransactionManager transactionManager) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -25,5 +25,4 @@
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
</bean>
|
||||
|
||||
<bean id="lobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler"/>
|
||||
</beans>
|
||||
|
||||
@@ -11,13 +11,13 @@
|
||||
<property name="jobRepository" ref="jobRepository" />
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
|
||||
<bean class="org.springframework.batch.core.configuration.support.JobRegistrySmartInitializingSingleton">
|
||||
<property name="jobRegistry" ref="jobRegistry"/>
|
||||
</bean>
|
||||
|
||||
<bean id="jobRepository"
|
||||
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"
|
||||
p:dataSource-ref="dataSource" p:transactionManager-ref="transactionManager" p:lobHandler-ref="lobHandler"/>
|
||||
p:dataSource-ref="dataSource" p:transactionManager-ref="transactionManager"/>
|
||||
|
||||
<bean id="jobExplorer"
|
||||
class="org.springframework.batch.core.explore.support.JobExplorerFactoryBean"
|
||||
|
||||
@@ -11,13 +11,13 @@
|
||||
<property name="jobRepository" ref="jobRepository" />
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
|
||||
<bean class="org.springframework.batch.core.configuration.support.JobRegistrySmartInitializingSingleton">
|
||||
<property name="jobRegistry" ref="jobRegistry"/>
|
||||
</bean>
|
||||
|
||||
<bean id="jobRepository"
|
||||
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"
|
||||
p:dataSource-ref="dataSource" p:transactionManager-ref="transactionManager" p:lobHandler-ref="lobHandler"/>
|
||||
p:dataSource-ref="dataSource" p:transactionManager-ref="transactionManager"/>
|
||||
|
||||
<bean id="jobOperator"
|
||||
class="org.springframework.batch.core.launch.support.SimpleJobOperator"
|
||||
|
||||
Reference in New Issue
Block a user