2

I'm writing a batch job that queries for Contact records following 2 sets of criteria and then adds them to an export object with corresponding flags of whether they fulfilled criteria set 1 or 2.

My problem is that it seems redundant to have the logic that tests which set of criteria each record falls under twice. First I query for all the records for both sets of criteria in start(), then in execute I have to test which one they fall into to do the right actions.

Is there a better way? In SQL, I would just select a dummy value for each record to record as I go whether they fall into category 1 or 2.

I'd rather not create 2 separate batch jobs here because as you can see, I'm going to be calling another batch job in the finish() method here.

Here's the code:

global class KlitaSyncBatchClass implements Database.Batchable<sObject>, Database.Stateful {
//insert into export table. Afterwards, call the batchable to go through the export table and create files.
    private List<SObjectField> fieldLabels;
    
    global Database.QueryLocator start(Database.BatchableContext bc) {
        // collect the batches of records or objects to be passed to execute
        String query = 'select ' + getAllFieldsForQuery('Contact') + ' from Contact where' +
            //a bunch of criteria  
        return Database.getQueryLocator(query);
        
    }
    global void execute(Database.BatchableContext bc, List<Contact> records){
        //go through records and insert into Export table.
        List<Misrad_Haklita_Export__c> exportRecords = new List<Misrad_Haklita_Export__c>();
        for (Contact c: records)
        {
            if(JAFIprocessExportRecord(c)){
                //add it to what will be inserted into export table
                exportRecords.add(new Misrad_Haklita_Export__c(Contact__c = c.Id, Contact_Status__c = 1));
                //update flag in contact
                c.Misrad_Haklita_Flag_1__c = Date.Today();
            }else if (PreFlightExportRecord(c)){
                 //add it to what will be inserted into export table
                exportRecords.add(new Misrad_Haklita_Export__c(Contact__c = c.Id, Contact_Status__c = 2));
                 //update flag in contact
                 c.Misrad_Haklita_Flag_2__c = Date.Today();
            }else{
                System.debug('Something went wrong. Didn\'t fulfill either criteria' + c);
            }
        }
        insert exportRecords; 
    }
    
    global void finish(Database.BatchableContext bc){
        // execute any post-processing operations
        // 
        // chain batchable class to go through export table and create text file.
    }
    
    private String getAllFieldsForQuery(String objectName){
        //dynamically get all the fields in the given object
    }
    
    //test whether the record should be part of the jafi process export (Export Part 1)
    private Boolean JAFIprocessExportRecord(Contact c)
    {
//half the logic that was in the where clause here 
        return true;
    }
    
     //test whether the record should be part of the pre-flight export (Export Part 2)
    private Boolean PreFlightExportRecord(Contact c)
    {
//half the logic that was in the where clause here
        return true;
    }
    
}
3
  • 3
    I think this is the only approach open to you here if you really want just a single batch. You could, of course, write two, chain the two together then have the second one invoke the planned post-processing batch.
    – Phil W
    Commented Dec 27, 2020 at 9:44
  • @PhilW Which do you think is more efficient?
    – sFishman
    Commented Dec 27, 2020 at 9:48
  • 3
    Depending on the complexity of distinguishing between the two groups of contact it could go either way. Remember that generally speaking anything done behind the Salesforce APIs is much more efficient than Apex code. However, there is the trade off here with the number of async calls. These are limited for each 24hr period.
    – Phil W
    Commented Dec 27, 2020 at 13:02

0

You must log in to answer this question.

Browse other questions tagged .