0

I recently created a custom object for logging certain scheduled Apex batch runs, but the code I added to the batchable class doesn't seem to be creating records in the custom object as intended.

The custom object is called "Batch Log" (batch_log__c), and has an auto name, a field for recording which batchable class created the log, and a Long Text field called "Log Text" (log_text__c). Here one of the batchable classes that I want to create a Batch Log when it runs:

global class ChinaLeadReassignmentBatch implements Database.Batchable<sObject> {

    String query;

    global ChinaLeadReassignmentBatch() {

    }

    global Database.QueryLocator start(Database.BatchableContext BC) {
        query = 'SELECT ID, OwnerID, CreatedDate, Status, LastActivityDate, Open_Activity_Count__c FROM Lead WHERE isConverted = FALSE AND CreatedDate = LAST_N_DAYS:30 AND CreatedDate < YESTERDAY AND Status = \'Open\' AND (OwnerID = \'00570000001kTxHAAU\' OR OwnerID = \'00570000001jPVZAA2\') AND LastActivityDate = NULL AND Open_Activity_Count__c = 0' ;
        return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext BC, List<Lead> scope) {

        List<Lead> toUpdate = new List<Lead>();
        Batch_log__c myLog = new Batch_Log__c();
        myLog.Batch_name__c = 'ChinaLeadReassignmentBatch';
        String myLogText = '';

        for (Lead l : scope){

            if (l.OwnerID == '00570000001kTxHAAU'){
                l.OwnerID = '00570000001jPVZAA2';
                myLogText += string.valueOf(system.now()) + ': Lead ' + l.id + ' reassigned to Lingling. /n';
            }

            if (l.OwnerID == '00570000001jPVZAA2'){ 
                l.OwnerID = '00570000001kTxHAAU';
                myLogText += string.valueOf(system.now()) + ': Lead ' + l.id + ' reassigned to Jacky. /n';
            }

            toUpdate.add(l);
        }

        update toUpdate;

        myLog.Log_text__c = myLogText;
        insert myLog;

    }

    global void finish(Database.BatchableContext BC) {

    }

}

Can anyone help me figure out why the Batch Log records never generate?


As requested, I obtained a debug log of the scheduled batch run:

31.0 APEX_CODE,FINEST;APEX_PROFILING,INFO;CALLOUT,INFO;DB,FINEST;SYSTEM,DEBUG;VALIDATION,INFO;VISUALFORCE,INFO;WORKFLOW,INFO
13:00:15.089 (89460631)|EXECUTION_STARTED
13:00:15.089 (89525778)|CODE_UNIT_STARTED|[EXTERNAL]|01p700000006AkU|ChinaLeadReassignmentBatch
13:00:15.095 (95981674)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:8
13:00:15.096 (96248892)|HEAP_ALLOCATE|[71]|Bytes:3
13:00:15.096 (96281520)|HEAP_ALLOCATE|[76]|Bytes:152
13:00:15.096 (96305859)|HEAP_ALLOCATE|[272]|Bytes:408
13:00:15.096 (96334990)|HEAP_ALLOCATE|[285]|Bytes:408
13:00:15.096 (96363152)|HEAP_ALLOCATE|[379]|Bytes:48
13:00:15.096 (96401314)|HEAP_ALLOCATE|[131]|Bytes:6
13:00:15.145 (145454547)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:52
13:00:15.145 (145479136)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:9
13:00:15.145 (145490183)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:20
13:00:15.145 (145516476)|METHOD_ENTRY|[1]|01p700000006AkU|ChinaLeadReassignmentBatch.ChinaLeadReassignmentBatch()
13:00:15.145 (145525144)|STATEMENT_EXECUTE|[1]
13:00:15.145 (145532878)|STATEMENT_EXECUTE|[1]
13:00:15.145 (145544832)|METHOD_EXIT|[1]|ChinaLeadReassignmentBatch
13:00:15.145 (145554306)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:8
13:00:15.145 (145561341)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:12
13:00:15.145 (145575823)|VARIABLE_SCOPE_BEGIN|[51]|this|ChinaLeadReassignmentBatch|true|false
13:00:15.145 (145624487)|VARIABLE_ASSIGNMENT|[51]|this|{}|0x731b056a
13:00:15.145 (145635057)|VARIABLE_SCOPE_BEGIN|[51]|BC|Database.BatchableContext|true|false
13:00:15.145 (145776516)|VARIABLE_ASSIGNMENT|[51]|BC|{"jobId":"7077000001M1Z5JAAV"}|0x5082d0e0
13:00:15.145 (145796024)|STATEMENT_EXECUTE|[51]
13:00:15.238 (214753674)|CUMULATIVE_LIMIT_USAGE
13:00:15.238|LIMIT_USAGE_FOR_NS|(default)|
  Number of SOQL queries: 0 out of 200
  Number of query rows: 0 out of 50000
  Number of SOSL queries: 0 out of 20
  Number of DML statements: 0 out of 150
  Number of DML rows: 0 out of 10000
  Maximum CPU time: 0 out of 60000
  Maximum heap size: 0 out of 12000000
  Number of callouts: 0 out of 0
  Number of Email Invocations: 0 out of 10
  Number of future calls: 0 out of 0
  Number of queueable jobs added to the queue: 0 out of 1
  Number of Mobile Apex push calls: 0 out of 10

13:00:15.238|CUMULATIVE_LIMIT_USAGE_END

13:00:15.214 (214789688)|CODE_UNIT_FINISHED|ChinaLeadReassignmentBatch
13:00:15.216 (216206964)|EXECUTION_FINISHED

I know there are Lead records in the system that should be pulled in by the batch's SOQL query, but the run is still not actually doing anything at all. So it appears the problem is not just with logging to my Batch Log object, but with getting the batch to actually run at all! What gives?

  • update toUpdate; could be throwing an error which would stop the log from being inserted. – BarCotter Mar 24 '15 at 14:47
  • Are you getting any information in your log files about errors from this code? If there is, share it here. If not, you'll have to use system.debug to try and pin down how far you are getting. BTW, are any of the fields on batch_log__c required? – Jagular Mar 24 '15 at 15:03
  • The scheduled batches are running without errors according to the Monitoring > Apex Jobs section in setup, so I don't think that's the problem. I will try some more intensive debug logging see what it actually going on. – OBerm Mar 24 '15 at 15:14
0

Take a look at the Monitor>Jobs>Apex Jobs for your job running and check the number of batches processed. If it says 0, check your SOQL statement to make sure something is actually being returned.

0

So, I figured out what was wrong. First of all, I was using Database.BatchableContext a bit wrong; I rechecked the documentation and ended up changing some code. My execute() method now reads:

        Batch_log__c myLog = new Batch_Log__c();
        myLog.Batch_name__c = 'ChinaLeadReassignmentBatch';
        String myLogText = '';

        for (Lead ld : scope){

            Lead l = (Lead)ld;

            if (l.OwnerID == '00570000001kTxHAAU'){
                //Batch Logic
                l.OwnerID = '00570000001jPVZAA2';
                leadsToUpdate.add(l);

                //Logging stuff
                myLogText += string.valueOf(system.now()) + ': Lead ' + l.id + ' reassigned to Lingling. /n ';
                System.debug(string.valueOf(system.now()) + ': Lead ' + l.id + ' reassigned to Lingling. /n ');
                system.debug('Lead ' + l.id + ' added to Update list.');

            } else if (l.OwnerID == '00570000001jPVZAA2'){ 
                //Batch logic
                l.OwnerID = '00570000001kTxHAAU';
                leadsToUpdate.add(l);

                //Logging stuff
                myLogText += string.valueOf(system.now()) + ': Lead ' + l.id + ' reassigned to Jacky. /n ';
                System.debug(string.valueOf(system.now()) + ': Lead ' + l.id + ' reassigned to Jacky. /n ');
                system.debug('Lead ' + l.id + ' added to Update list.');
            }

        }

    update leadsToUpdate;
    system.debug('Updated leads in Update list');

    myLog.Log_text__c = myLogText;
    system.debug('Set batch log text to: ' + myLogText);
    insert myLog;
    system.debug('Inserted myLog, Batch Log ID is: ' + myLog.id);

}

The main difference being

for (Lead ld : scope){

    Lead l = (Lead)ld;

and then running my logic on this extracted Lead object rather than directly within the scope. At least that's what I think fixed it, since it's working now. and that was the only real semantic change.

As for the Batch Log, I was being extremely dumb and just not looking within the correct view to see that the Batch Logs were in fact being generated just fine.

Anyway, all seems to be working fine now.

Cheers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.