Announcement Announcement Module
Collapse
No announcement yet.
Skip Item in a RepeatTemplate Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Skip Item in a RepeatTemplate

    Hi,
    I'm new to Spring-Batch and first I have to say it is great and help me a lot.
    I'm using a RepeatOperationsStepFactoryBean in my hibernateJob and write my items within a chunk.
    This works all fine!!!
    But when an item throws an exception in a chunk, spring batch retry the whole chunk with the item that throws the exception. But I don't want to retry this item, Spring-Batch should execute with the next item.

    Here is my job-conf

    Code:
    <import resource="classpath:/batchJob-context.xml" />
    	<bean id="buLiStatisticJob" parent="simpleJob">
    		<!-- Job should never be restarted, but should always be run as part of a new JobInstance -->
    		<property name="restartable" value="false" />
    		<property name="steps">
    			<bean id="buLiStatisticStep" class="org.springframework.batch.core.step.item.RepeatOperationsStepFactoryBean">
    				<property name="jobRepository" ref="jobRepository" />
    				<property name="transactionManager" ref="batchTxManager" />
    				<!-- The Step can be run only once -->
    				<property name="startLimit" value="1" />
    				<property name="allowStartIfComplete" value="true" />
    				<property name="listeners">
    					<list>
    						<bean class="org.kingdeloui.buli.batch.listener.BuLiStatisticItemListener" />
    						<bean class="org.kingdeloui.buli.batch.listener.BuLiStatisticStepListener" />
    					</list>
    				</property>
    				<property name="itemReader" ref="buLiItemReader" />
    				<property name="itemWriter" ref="buLiItemWriter" />
    				<!-- (Inner) Loop -->
    				<property name="chunkOperations">
    					<bean class="org.springframework.batch.repeat.support.RepeatTemplate">
    						<property name="listeners">
    							<list>
    								<ref bean="buLiStatisticWriter1" />
    								<ref bean="buLiStatisticWriter2" />
    								<ref bean="buLiStatisticWriter3" />
    							</list>
    						</property>
    						<property name="completionPolicy">
    							<bean class="org.springframework.batch.repeat.policy.SimpleCompletionPolicy">
    								<property name="chunkSize" value="2" />
    							</bean>
    						</property>
    					</bean>
    				</property>
    				<!-- (Outer) Loop -->
    				<property name="stepOperations">
    					<bean class="org.springframework.batch.repeat.support.RepeatTemplate">
    						<property name="exceptionHandler">
    							<bean class="org.springframework.batch.repeat.exception.SimpleLimitExceptionHandler">
    								<property name="limit" value="3" />
    								<!-- Count exceptions for the whole (outer) loop  -->
    								<property name="useParent" value="true" />
    								<property name="exceptionClasses" value="java.lang.Exception" />
    							</bean>
    						</property>
    					</bean>
    				</property>
    			</bean>
    		</property>
    	</bean>
    Thx.

  • #2
    This should be possible, but if you really need to use RepeatOperationsStepFactoryBean, then probably only with a bit of effort on your part. Actually I can't see why you need RepeatOperationsStepFactoryBean. Is there any chance you could use one of the other *StepFactoryBean (probably your listeners can be implemented as step execution listeners, and then it would be trivial)?

    Hopefully in 1.1 I will be able to say "just wrap your repeat operations in a retry interceptor" (I don't think it works right now, but if you try it and it does, that's great). Meanwhile, if you can't use another factory bean, I think you will have to write something that wraps your ItemReader/Writer and that handles the exception.

    Comment


    • #3
      Hi Dave,

      I try out the ItemOrientedStep for my Job. So I could use a ItemSkipPolicyItemHandler for my problem described above. It works fine!!!

      But I have found a bug. I'm using a stateful Session, so when I start my Job I get the following Exception:

      Code:
      INFO: Job: [SimpleJob: [name=buLiStatisticJob2]] failed with the following parameters: [{}{}{}{}]
      java.lang.NullPointerException
      	at org.springframework.batch.item.database.HibernateCursorItemReader.mark(HibernateCursorItemReader.java:185)
      	at org.springframework.batch.core.step.item.SimpleItemHandler.mark(SimpleItemHandler.java:108)
      	at org.springframework.batch.core.step.item.ItemSkipPolicyItemHandler.mark(ItemSkipPolicyItemHandler.java:223)
      	at org.springframework.batch.core.step.item.ItemOrientedStep.execute(ItemOrientedStep.java:267)
      	at org.springframework.batch.core.job.SimpleJob.execute(SimpleJob.java:125)
      	at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:86)
      	at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:49)
      	at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:81)
      	at org.kingdeloui.batch.BuLiStatisticJob.testLaunchJob(BuLiStatisticJob.java:31)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
      	at java.lang.reflect.Method.invoke(Unknown Source)
      	at org.springframework.test.context.junit4.SpringTestMethod.invoke(SpringTestMethod.java:163)
      	at org.springframework.test.context.junit4.SpringMethodRoadie.runTestMethod(SpringMethodRoadie.java:233)
      	at org.springframework.test.context.junit4.SpringMethodRoadie$RunBeforesThenTestThenAfters.run(SpringMethodRoadie.java:333)
      	at org.springframework.test.context.junit4.SpringMethodRoadie.runWithRepetitions(SpringMethodRoadie.java:217)
      	at org.springframework.test.context.junit4.SpringMethodRoadie.runTest(SpringMethodRoadie.java:197)
      	at org.springframework.test.context.junit4.SpringMethodRoadie.run(SpringMethodRoadie.java:143)
      	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:142)
      	at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
      	at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
      	at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
      	at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
      	at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
      	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
      	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
      	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
      	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
      	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
      	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
      If I use a stateless Session it works fine!

      Comment


      • #4
        Glad it worked for you. You can also use the SkipLimitStepFactoryBean to save yourself some configuration:

        http://static.springframework.org/sp...n.html#d0e3560

        I'm not sure why that exception would happen. The only way I can think of is if mark() was called before open(), or after close(). Can you create an issue in JIRA with the full details?

        Comment


        • #5
          Hi lucasward,

          I have created an Issue in Jira.

          http://jira.springframework.org/browse/BATCH-615

          Comment

          Working...
          X