Cygnusx1
Cygnusx1

Reputation: 5409

How to make ItemReader reads 2 tables

I have to create a batch job to do financial reconciliation. Right now i have 3 steps:

step 1 : Read an XML from the third party , convert this in our domains object, write in DB(table 1)

step 2 : Read a flatFile from our transactions datastore, write in DB (Table2)

step 3 : Read both table1 and table 2 in an aggregatorObject, process both list to find differences and set status code, write a status code in table 2

My problem is with step3. I can't find a good solution to have my ItemReader reading from 2 SQL.

I started with a custom ItemReader like this :

package batch.concilliation.readers;


@Component("conciliationReader")
public class TransactionReader implements ItemReader<TransactionsAgragegator>{

private final Logger log = Logger.getLogger(TransactionReader.class);

@Autowired
private ConciliationContext context;

@Autowired
private ServiceSommaireConciliation serviceTransactionThem;

@Autowired
private ServiceTransactionVirement serviceTransactionUs;


@Override
public TransactionsAgragegator read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {

    TransactionsAgragegator agregator = new TransactionsAgragegator();

    SommaireConciliationVirementInterac sommaire = serviceSommaireThem.findByRunNo(context.getRunNo());

    List<TransactionVirement> journalSic = serviceTransactionUs.findByTimestamp(sommaire.getBeginDate(), sommaire.getEndDate()); 

    // on place ces deux listes dans l'objet agregteur.
    agregator.setListeTransactionThem(sommaire.getPayments());
    agregator.setListeTransactionsUs(journalSic);

    return aggregator;
}

}

This Reader use two services already implemented (DAO) that read both tables and return domain objects. I take the two lists of transaction from us and from them and put them in an aggregator object. This object would be passed to the ItemProcessor and i could do my business logic... but this reader start an infinite loop since it will never read null.

I read about ItemReaderAdapter, but i still have the same problem of looping over a collection until i get a null.

So in summary, i want to read 2 different tables and get 2 List:

List<TransactionThirdParty>
List<TransactionHome>

then My ItemProcesssor would check to see if both lists are equals or not, is one has more or less transactions then the other..etc

Any Spring Batch expert can suggest something?

Upvotes: 2

Views: 2812

Answers (1)

Serkan Arıkuşu
Serkan Arıkuşu

Reputation: 5619

The problem here is that your first two steps are chunk oriented but the third one is not. While the first two may have the usual read-process-write cycle, the third step while dependent on the first two is a one time operation. It is no more different then copying a file in batch domain.

So you should not use the ItemReader way here, because you do not have an exit criteria (that is why you never get nulls from the reader, it cannot know when the source is exhausted since it does not deal with a line or record.

That is where TaskletStep helps

The Tasklet is a simple interface that has one method, execute, which will be a called repeatedly by the TaskletStep until it either returns RepeatStatus.FINISHED or throws an exception to signal a failure.

So implement your third step as a Tasklet instead of chunk oriented way.

Upvotes: 2

Related Questions