title: StaxEventItemReader - skip XML fragments processed in previous Job executions
body: <p>When working with CSV files and restarting a FAILED Job, a StepExecutionListner and associated beforeStep( ....) method can be used to position
  the reader within the file. So the code could look something like:</p>
  
  <pre><code>public void beforeStep(StepExecution stepExecution) {
  
      ExecutionContext executionContext = stepExecution.getExecutionContext();
  
      if (executionContext.containsKey(getKey(LINES_READ_COUNT))) {
  
          long lineCount = executionContext.getLong(getKey(LINES_READ_COUNT));
  
          LineReader reader = getReader();
          Object record = "";
          while (reader.getPosition() &lt; lineCount &amp;&amp; record != null) {
              record = readLine();
          }
      }
  } // Or something similar
  </code></pre>
  
  <p><strong>My question is how do you achieve the same thing when working with a StaxEventItemReader?</strong></p>
  
  <p>My batch_step_execution_context looks something like <code>{"string":"StaxEventItemReader.read.count","int":6}</code>. So in my case the 
  the first 5 XML fragment were successfully processed and upon restarting the Job I would like to start processing from XML fragment number 6 onwards.</p>
  
  <p>Given the config below, how would I position the reader within the XML file? </p>
  
  <pre><code>&lt;batch:job id="reportJob" restartable="true"&gt;
      &lt;batch:step id="step1"&gt;
          &lt;batch:tasklet&gt;
              &lt;batch:chunk reader="xmlItemReader" writer="cvsFileItemWriter" processor="filterReportProcessor"
                  commit-interval="1"&gt;
              &lt;/batch:chunk&gt;
              &lt;batch:listeners&gt;
                  &lt;batch:listener ref="step1Listener" /&gt;
              &lt;/batch:listeners&gt;
          &lt;/batch:tasklet&gt;
      &lt;/batch:step&gt;
  &lt;/batch:job&gt;
  
  &lt;bean id="step1Listener" class="com.mkyong.listeners.Step1Listener" /&gt;
  
  &lt;bean id="filterReportProcessor" class="com.mkyong.processor.FilterReportProcessor" /&gt;
  
  &lt;bean id="xmlItemReader" class="org.springframework.batch.item.xml.StaxEventItemReader"&gt;
      &lt;property name="fragmentRootElementName" value="record" /&gt;
      &lt;property name="resource" value="classpath:xml/report.xml" /&gt;
      &lt;property name="unmarshaller" ref="reportUnmarshaller" /&gt;
  &lt;/bean&gt;
  
  &lt;!-- Read and map values to object, via jaxb2 --&gt;
  &lt;bean id="reportUnmarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"&gt;
      &lt;property name="classesToBeBound"&gt;
          &lt;list&gt;
              &lt;value&gt;com.mkyong.model.Report&lt;/value&gt;
          &lt;/list&gt;
      &lt;/property&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p><strong>Environment</strong> - spring-batch-core-2.2.0; spring-core-3.2.2</p>
  
  <p><strong>Test Input File</strong></p>
  
  <p>Convert a XML file into a CSV file.</p>
  
  <pre><code>&lt;company&gt;
      &lt;record refId="1001"&gt;
          &lt;name&gt;mkyong&lt;/name&gt;
          &lt;age&gt;31&lt;/age&gt;
          &lt;dob&gt;31/8/1982&lt;/dob&gt;
          &lt;income&gt;200,000&lt;/income&gt;
      &lt;/record&gt;
      &lt;record refId="1002"&gt;
          &lt;name&gt;kkwong&lt;/name&gt;
          &lt;age&gt;30&lt;/age&gt;
          &lt;dob&gt;26/7/1983&lt;/dob&gt;
          &lt;income&gt;100,999&lt;/income&gt;
      &lt;/record&gt;
      &lt;record refId="1003"&gt;
          &lt;name&gt;joel&lt;/name&gt;
          &lt;age&gt;29&lt;/age&gt;
          &lt;dob&gt;21/8/1984&lt;/dob&gt;
          &lt;income&gt;1,000,000&lt;/income&gt;
      &lt;/record&gt;
      &lt;record refId="1004"&gt;
          &lt;name&gt;leeyy&lt;/name&gt;
          &lt;age&gt;29&lt;/age&gt;
          &lt;dob&gt;21/3/1984&lt;/dob&gt;
          &lt;income&gt;80,000.89&lt;/income&gt;
      &lt;/record&gt;
      &lt;record refId="1005"&gt;
          &lt;name&gt;Grant&lt;/name&gt;
          &lt;age&gt;29&lt;/age&gt;
          &lt;dob&gt;21/3/1984&lt;/dob&gt;
          &lt;income&gt;80,000.89&lt;/income&gt;
      &lt;/record&gt;
  &lt;/company&gt;
  </code></pre>
  
  <p><strong>Test Run 1</strong></p>
  
  <p>After processing two records in the input file, I forced a RunTimeException.</p>
  
  <pre><code>batch_job_execution ---&gt;&gt;  "FAILED";"FAILED";"java.lang.RuntimeException: Get me out of here!
  
  batch_step_execution_context ---&gt;&gt; {"string":"StaxEventItemReader.read.count","int":2}
  
  Output CSV file ---&gt;&gt; 1001,mkyong,31,31/08/1982,200000
                        1002,kkwong,30,26/07/1983,100999
  </code></pre>
  
  <p><strong>Test Run 2</strong></p>
  
  <p>Process all "remaining data", so expecting .... refId="1003", refId="1004", refId="1005"</p>
  
  <pre><code>batch_job_execution ---&gt;&gt;  "COMPLETED";"COMPLETED";"''";"2015-01-25 16:18:08.587"
  
  batch_step_execution_context ---&gt;&gt;  {"string":"StaxEventItemReader.read.count","int":6}
  
  
  Output CSV file ---&gt;&gt; 1001,mkyong,31,31/08/1982,200000
                        1002,kkwong,30,26/07/1983,100999
                        1003,joel,29,21/08/1984,1000000
                        1004,leeyy,29,21/03/1984,80000.89
                        1005,Grant,29,21/03/1984,80000.89
  </code></pre>
  
  <p><strong>Test Result</strong></p>
  
  <p>Unfortunately it looks like the StaxEventItemReader is reading from the beginning of the file, rather than re-positioning itself based on the value of StaxEventItemReader.read.count which is set to 2 after the first test.</p>