John
John

Reputation: 11831

Grails Spring Batch - pattern for CRUD from record format (how to implement Delete)

I'm looking at using Spring Batch within Grails using the Grails Spring Batch plugin.

If I have a number of fixed length records referring to an entity in my input file, where part of that record indicates whether the record is a new item, an existing item that should be updated or an existing item that should be deleted, what is the best pattern for integrating into the Spring Batch pattern?

So if my possible records look like this:

// create new record of type AA, data is 12345
AAN12345 

// update record of type AA, data is 12345 (assume that the data is the key and I can find the existing AA item using this key)
AAU12345

// delete record of type AA using 12345 as the key
AAD12345

I'm happy with a LineMapper that takes a line from a FlatFileItemReader and creates a new item and passes it to a writer for saving.

The LineMapper could look like:

class AaLineMapper implements LineMapper<AaItem> {

    @Override
    AaItem mapLine(String line, int lineNumber) throws Exception {
        switch (line[0..1]) {
            case 'N':
                AaItem item = new AaItem()
                // set fields here based on line
                return item
                break

            case 'U':
                // possibly this?
                AaItem item = AaItem.findByKey(someValueWithinLine)
                // set fields here based on line
                return item
                break

            case 'D':
                // not sure on this one, deleting and returning null doesn't seem to work
                // I thought the writer should delete the object?
                break
        }
    }
}

However, for update, am I to assume that the best way is to use Item.findByKey(12345) within the LineMapper and then modify the Item and call save() within the writer?

How do I implement a delete? If I return a null from my LineMapper then the application seems to stop. I thought the writer should be deleting the object, not this? Or do I just use findByKey(12345), then pass to the writer with a delete flag set?

Apologies for the basic question, this is Day 1 of using the framework. I'm interested in understanding best-practices please.

Upvotes: 0

Views: 90

Answers (1)

Joshua Moore
Joshua Moore

Reputation: 24776

You are close, but not quite there. What you really need your line mapper to produce is an instance of a class that contains not only the instance of the domain class to effect but also a property to indicate what action needs to be taken (presumably by an item processor, or a classifying item writer, depending on your requirements).

So something like this might work:

class MyActionContainerClass {
  Object target
  String actionType // U, D, N
}

Upvotes: 1

Related Questions