Spring Batch - 作业实例已存在:JobInstanceAlreadyCompleteException

时间:2014-03-17 13:32:26

标签: java spring batch-processing

我在Spring应用程序中编写了一个简单的调度程序。我运行我的本地服务器,几秒钟后,在类Importer中,checker.start()每5秒调用一次,就像我在配置文件中配置一样。

之后,此方法使用JobLauncher调用Job,此处出现错误。

  

org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException:   作业实例已存在,并且对于参数= {}已完成。如果   你想再次运行这个工作,改变参数。

我找到了一个解决方法,如何使用注释修复它,但我想保持这种方式。

提前谢谢

public class Importer {

    private Checker checker;

    public Importer() {
    }

    public void myMethod() {
        try {
            checker.start(); 
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

使用.xml文件:

<bean id="schedulerTask"
    class="org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean">
    <property name="targetObject" ref="fileimport" />
    <property name="targetMethod" value="myMethod" />
</bean>

<bean id="fileimport" />
    <property name="targetMethod" value" class="com...Importer">
    <property name="checker">
        <bean id="checker" class="com...Checker">

        </bean>
    </property>
</bean>

<bean id="scheduledTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
    <property name="timerTask" ref="schedulerTask" />
    <property name="delay" value="${xyz.startdelay}" />
    <property name="period" value="${xyz.checkinterval}" />
</bean>

<bean class="org.springframework.scheduling.timer.TimerFactoryBean">
    <property name="scheduledTimerTasks">
        <list>
            <ref local="scheduledTask" />
        </list>
    </property>
</bean>

属性文件:

  

xyz.checkinterval = 5000

     

xyz.startdelay = 0

在班级Checker中我有方法:

static ConfigurableApplicationContext applicationContext = new ClassPathXmlApplicationContext("/simplefile-context.xml");
Job job = (Job) applicationContext.getBean("fileBatch");
JobLauncher launcher = (JobLauncher) applicationContext.getBean("jobLauncher");
public void start() throws ClientProtocolException, IOException {
    // ...
    try {
        launcher.run(job, new JobParameters());
        } catch (Exception e) {
        e.printStackTrace();
    }
}

和我的&#34; simplefile-context.xml&#34;文件看起来像这样:

<bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
    <property name="transactionManager" ref="transactionManager"/>
</bean>

<!-- bean for lauching the job -->
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
    <property name="jobRepository" ref="jobRepository" />
</bean>

<task:executor id="taskExecutor" pool-size="100" />

<!--                                   -->
<!--                JOBS               -->
<!--                                   -->
<batch:job id="fileBatch" restartable="true">
    <batch:step id="readLines" >
        <batch:tasklet task-executor="taskExecutor" >
            <batch:chunk reader="fileReader" writer="fooWriter" commit-interval="100" />
        </batch:tasklet>
    </batch:step>
</batch:job>

<bean id="fileReader" class="org.springframework.batch.item.file.FlatFileItemReader">
    <property name="linesToSkip" value="1"/>
    <property name="resource" value="file:./src/main/resources/sample.csv" />
    <property name="lineMapper" ref="lineMapper" />
</bean>

<bean id="lineMapper" class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
    <property name="lineTokenizer" ref="lineTokenizer"/>
    <property name="fieldSetMapper" ref="fieldsetEntityMapper"/>
</bean>

<bean id="lineTokenizer" class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
    <property name="delimiter" value=";" />
    <property name="names" value="field1,field2,field3,field4,field5,field6,field7" />
    <property name="strict" value="false"/>
</bean>

<bean id="fieldsetEntityMapper" class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
    <property name="targetType" value="com...model.ModelObject"/>
    <property name="customEditors">
        <map>
            <entry key="java.lang.Double">
                <bean class="org.springframework.beans.propertyeditors.CustomNumberEditor">
                    <constructor-arg index="0" value="java.lang.Double"/>
                    <constructor-arg index="1" value="true"/>
                </bean>
            </entry>
        </map>
    </property>
</bean>

<bean id="fooWriter" class="com...springbatch.writer.FooWriter" />

4 个答案:

答案 0 :(得分:21)

使用当前设置,您只能启动一次作业。

    launcher.run(job, new JobParameters());

作业是id标识的唯一参数。目前,没有办法根据参数进行区分。而不是添加new JobParameters()使用JobParamtersBuilderBuilder并添加当前日期和时间。

JobParametersBuilder builder = new JobParametersBuilder();
builder.addDate("date", new Date());
launcher.run(job, builder.toJobParameters());

这将允许您多次运行作业。

答案 1 :(得分:2)

将行添加到jobBuilderFactory

.incrementer(new RunIdIncrementer())

下一步(当您使用jobLauncher和自定义JobParameters手动运行作业时)

paramsBuilder.getNextJobParameters(job);

代替 .addDate("date", new Date());,就像他们劝告您

答案 2 :(得分:1)

随着我遇到相同的错误并在测试中传递相同的JobParameters,Yon还可以花一些时间使其变得更加独特。

JobParameters jobParameters = new JobParametersBuilder()
                .addDate("date", new Date())
                .addLong("time",System.currentTimeMillis()).toJobParameters();

答案 3 :(得分:0)

在Application.property文件中 添加缺少的新字段。

spring.batch.initialize-schema =总是 spring.batch.job.enabled = false