0
votes

I am using Spring batch Item reader. in Item reader read method calling Stored procedure. Once we get the result from stored procedure it is returning to writer. but again it is going to read method. so read is executing repeatedly.

can any one suggest that how can I restrict read method to call only once for job execution.

*Note : StoredprocedureitemReader is not our requirement. we need to use itemreader read only

Please help on this

2

2 Answers

0
votes

If I understood you correctly, you need to read once and write many times. You can do that using the store procedure to get the results the first time the read() method is invoked and all remaining times you return the objects readed, one by one.

0
votes

here's an example of a reader that loads up a queue of items once, and reads from the same queue. This is analogous to your use case of one call to a Stored Procedure and multiple "writes".

package de.incompleteco.spring.batch.item;

import java.util.PriorityQueue;
import java.util.Queue;
import java.util.UUID;

import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.NonTransientResourceException;
import org.springframework.batch.item.ParseException;
import org.springframework.batch.item.UnexpectedInputException;

import de.incompleteco.spring.batch.domain.Record;

public class SingleItemReader implements ItemReader<Record> {

    private Queue<String> values = null;

    public Record read() throws Exception, UnexpectedInputException,ParseException, NonTransientResourceException {
        //check the queue
        if (values == null) {
            //load
            loadQueue();
        }//end if
        //return
        return getRecord(values.poll());
    }

    private Record getRecord(String value) {
        //init
        Record record = null;
        //check for null
        if (value != null) {
            record = new Record();
            record.setId(UUID.randomUUID());
            record.setValue(value);
        }//end if
        //return
        return record;      
    }

    private synchronized void loadQueue() {
        //generate a bunch of data and add to the queue
        if (values == null) {
            System.out.println("calling load of the queue");
            values = new PriorityQueue<String>();
            for (int i=0;i<100;i++) {
                values.add("hello " + i);
            }//end for
        }//end if
    }

}

here's the writer for the example

package de.incompleteco.spring.batch.item;

import java.util.List;

import org.springframework.batch.item.ItemWriter;

import de.incompleteco.spring.batch.domain.Record;

public class SystemItemWriter implements ItemWriter<Record> {

    public void write(List<? extends Record> items) throws Exception {
        System.out.println("starting write...");
        System.out.println(items);
        System.out.println("...finished write");
    }

}

the batch configuration is as follows;

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:batch="http://www.springframework.org/schema/batch"
    xmlns:task="http://www.springframework.org/schema/task"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

    <batch:job id="singleReadJob">
        <batch:step id="singleReadJob.step1">
            <batch:tasklet>
                <batch:chunk reader="singleReader" writer="multiWriter" commit-interval="10"/>
            </batch:tasklet>
        </batch:step>
    </batch:job>

    <bean id="singleReader" class="de.incompleteco.spring.batch.item.SingleItemReader"/>

    <bean id="multiWriter" class="de.incompleteco.spring.batch.item.SystemItemWriter"/>

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

    <bean id="jobLauncher"
        class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
        <property name="jobRepository" ref="jobRepository"/>
        <property name="taskExecutor" ref="taskExecutor"/>
    </bean>

    <bean id="jobExplorer"
        class="org.springframework.batch.core.explore.support.MapJobExplorerFactoryBean">
        <property name="repositoryFactory" ref="&amp;jobRepository"/>
    </bean>

    <task:executor id="taskExecutor"/>

    <bean id="transactionManager"
        class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>
</beans>