0
votes

Here is my requirement : Create a batch job that 1. Fetches discount programs from Discount table for specific search critieria 2. For each discount program fetched in Step1, Get sales records for sales that fit the discount program dates Get additional details for sales from some other tables 3. Write the sales records into ReportTable 4. update discount table with status

3 options for implementations I could think of are : Option 1: (a) Create a DiscountReader that extends JdbcCursorItemReader that fetches discount programs based on dates and other criteria _ returns objects of type DiscountObj. (b) Created a SalesProcessor that implements ItemProcessor, with a SalesReader and SalesWriter. -> SalesReader should read records from salestable based on the current DiscountObj. -> SalesWriter to write the date fetched by SalesReader into database. (c) create DiscountWriter to update status into Discount table.

Option 2: (a) Create DiscountReader with a SalesReader inside ( ItemReader within ItemReader approach.)- which calls Salesreader for each DiscountObj being read. (b) Create SalesWriter to write the date fetched by SalesReader into database.

In any case, the parameters for the query executed by SalesReader is dynamic since it has to be extracted from the current DiscountObj. Are these the only 2 approaches or is there a better approach ?

If I inject the SalesReader into SalesProcessor/ DiscountReader, the open() method is being called before the preparedstatementsetter is set with the query parameters.

If I create instances of the SalesReader in SalesProcessor/ DiscountReader I get the exception that the Reader is not open.


Option 3: Create DiscountReader to read discounts. Create SalesProcessor which calls a DAO to get the sales records based on the discpuntObj Pass the data returned from the DAO to the writer.

Please help.

2
as long as you do not need a transaction over all business steps, you can split the work in different spring batch steps/jobs - Michael Pralow

2 Answers

1
votes

Make readers, processors and writers separated as much as possible: every component has a specific job and mixing is usually a bad pratice.
You use-case is a common one and - if I understood correctly - your difficulties are related to reader.
Split it in two components:

  • Reader: use a single SQL cursor-based reader based of a join between discount+sales tables
  • Processor: for every record fetched use a DAO to enrich record with additionals datails

Add more processors as long as you need more data manipulation, than writing should be straightforward

This is just a proposal of solution; I hope you can get insipiration from that. Good work :)

0
votes

I get a feel that you can write a join query as everything is based upon something you fetch earlier.

You may write a listner for reader/writer as well, if you need certain information using JobExecutionListenerSupport(refer beforeJob,afterJob)

If you follow above, this is going to be a simple getting started use case of spring batch.