Announcement Announcement Module
Collapse
No announcement yet.
Itemreader that does nothing Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Itemreader that does nothing

    hi All,

    I have some requirement, where i have to read n number of records based on some criteria, then process them and after processing all records have to generate a summary report.

    I have made following configuration using simple steps:

    1. Step 1,
    a. read all the records from database using itemreader,
    b. Call the processr to process each record and also populates an object containing summary data as was the record processed successfully or not, in execution context,
    c.an itemwriter, dummy one, just logs in each records state (as i dont want to write the summary data now for each record, but as a whole for full processing)

    2. Step 2,
    a. want an itemreader that does nothing as i dont have anything to do now but just print the summary data,
    b. processor, again nothing to do at this step,
    c. lastly a itemwriter that will now fetch summary from execution context and print the summary data.

    Now my question is

    1. is my approach correct,
    2. if yes, how do i configure dummy itemreader, writer and processors
    3. if no, then how should i proceed for the same.

    Thanks in advance.

  • #2
    Hi,

    I am also having similar requirement, can anybody suggest a solution.

    Comment


    • #3
      Your step 2 should be a TaskletStep, which is a step that just runs Tasklet.execute(). You'll need to create a custom Tasklet implementation that prints the summary data.

      Comment


      • #4
        Can you please provide some sample for that...Also current config leads my step 2 to be executed as many as step1 number of times...Will implementing tasklet ensure single running of step2???????
        Last edited by puneetswarup; Mar 13th, 2009, 08:51 AM.

        Comment


        • #5
          The docs contain information on the tasklet step. Hopefully that will clear things up.

          In 1.x:
          http://static.springframework.org/sp...n.html#d0e4366

          In 2.0:
          http://static.springframework.org/sp...p.html#d0e2984

          Comment


          • #6
            Why do you even need a second step? Can't you write it out in an afterStep method on step 1?

            Comment


            • #7
              I think that the TaskletStep is the better approach. If an exception is thrown from an afterStep method, the framework has no way to handle it, so it is swallowed (merely logged out and the step will still be COMPLETED). If you put the same logic in a Tasklet then the exception will result in the step failing, which is most likely what you would want.

              Comment


              • #8
                Thank you for all the suggestions. I would like to go with Tasklet. But i need to produce XML output of the summary element. For that i am extendingStaxEventItemWriter. How do i integrate both?

                Comment


                • #9
                  Make the StaxEventItemWriter a property of the Tasklet. Call it from the execute() method as many times as you need to.

                  Comment


                  • #10
                    Now that i have stored my summary object (result of step1) in executionContext, how do i get that in this tasklet?

                    Comment


                    • #11
                      What version of spring batch are you using?

                      You'll need to move it from the step's ExecutionContext to the job's. This can be done in an afterStep method:

                      Code:
                      public ExitStatus afterStep(StepExecution stepExecution) {
                      	ExecutionContext stepContext = stepExecution.getExecutionContext();
                      	ExecutionContext jobContext = stepExecution.getJobExecution().getExecutionContext();
                      	String exitCode = stepExecution.getExitStatus().getExitCode();
                      	for (String key : keys) {
                      		jobContext.put(key, stepContext.get(key));
                      	}
                      	return null;
                      }
                      If you're using Spring Batch 2.0, there is a listener included in the framework to do just this: ExecutionContextPromotionListener

                      Comment


                      • #12
                        Version 2.0.0.M3.

                        Its already in Jobs execution context. Even i am getting

                        public RepeatStatus execute(StepContribution stepContribution, AttributeAccessor attributeAccessor)

                        for tasklet interface.

                        Please suggest how do i proceed.
                        Last edited by puneetswarup; Mar 13th, 2009, 11:00 AM.

                        Comment


                        • #13
                          You should use 2.0.0.RC1.

                          Chunk-oriented steps should not store anything to the Job's ExecutionContext until after the step is complete. This is because the only the Step's ExecutionContext is persisted during step execution. Or in other words, if your step fails half way through step1, you'll lose any information you've saved. Always store to the Step's ExecutionContext during processing and use the promotion listener to move the content afterward.

                          For the tasklet:
                          Code:
                          public RepeatStatus execute(StepContribution stepContribution, AttributeAccessor attributeAccessor) {
                              ExecutionContext jobContext = this.stepExecution.getJobExecution().getExecutionContext();
                              this.staxEventItemWriter.open(0, false);
                              for(Object obj : (List)jobContext.get(MY_KEY)) {
                                  this.staxEventItemWriter.write(obj)
                              }
                              this.staxEventItemWriter.close()
                          }
                          
                          @BeforeStep
                          public void storeStepExecution(StepExecution stepExecution) {
                              this.stepExecution = stepExecution;
                          }
                          At this point you're making Step2 awfully chunk-oriented-looking, but without the benefits like restartability. Also it's pretty strange to generate a huge object of all your step1 data to be passed to step2. Why not just use a StaxEventItemWriter in step1 to write it out at the same time? Then it would be restartable, cleaner, faster, and use less memory.

                          Comment


                          • #14
                            Well, the data that i want to write to xml is summary of the processing of 1st step ie only data such as count of records processed and number of failed and as such, thus i moved that part out of step 1 as the writer would be called each time a record is processed there by always overwriting the xml output file.

                            In below code snippet how do i inject the stepExecution into the taskLet bean?

                            Comment


                            • #15
                              Ok, i see now.

                              The stepExecution is being injected via the @BeforeStep method as now seen in the snippet.

                              Comment

                              Working...
                              X