4

I am attempting to use batch to handle a deserialized JSON response of 12,000 records to upsert objects.

I currently have a class that makes the webservice callout, deserializes the response, sets the value of new instances of my custom object to the response values, and adding these new custom object instances to a list, and upserting the list. I am trying to use batch due to the 10000 DML limit.

How do I pass my list of custom objects from currentCalloutClass into the batch class to handle the upsert? Is there a better a way to do this?

The code below results in:

Illegal conversion from List < Custom_Object__c > to Database.QueryLocator error

Which makes sense, but I do not need to run a query, I am creating new instances of the object and already have the list that I need to execute. Should I be converting my currentCalloutClass into a batchable class? Do I have to set a query?

currentCalloutClass:

public class currentCalloutClass {

     public void currentCalloutClass(){
          jsonStr = '';
          List <Custom_Object__c> cObjList = new list <Custom_Object__c()>;

          ...webservice response stored in jsonStr...

          JSON2ApexConverter calloutGet = (JSON2ApexConverter )JSON.deserialize(jsonStr, JSON2ApexInfo.class);

          for(i = 0; i < calloutGet.object.size(); i++) {
              Custom_Object__c cObj = new Custom_Object__c;
              cObj.custom_field__c = calloutGet.object.field_1;
              cObjList.add(cObj);
              }     

         }
    Database.executeBatch(new batchTestNew(cObjList), 250);

}

batchTestNew

global class batchTestNew implements Database.Batchable<sObject>{

public List <Contact> accountsToParseSet = new List<Custom_Object__c>();

   global batchTestNew(List<Custom_Object__c> accountsToParseGet){
   accountsToParseSet = accountsToParseGet;          
   }

   global Database.QueryLocator start(Database.BatchableContext BC){
      return accountsToParseSet;
   }

   global void execute(Database.BatchableContext BC, 
                       List<sObject> scope){
      for(sObject s : scope){
           upsert accountsToParseSet;
                  }      
      update scope;
   }

   global void finish(Database.BatchableContext BC){

   }

}
8

You can use this signature instead:

public List<SObject> start(Database.BatchableContext context)
{
    return myRecords;
}

Please note that your batch classes do not need to be global and you should only use that access modifier under limited circumstances, for example while writing a REST endpoint or managed package. You should instead use public.

| improve this answer | |
  • 1
    Bingo! +Thanks for the tips on scope, I figured it wasn't necessary, but I just copied the example from the SF docs. – S.B. May 7 '18 at 15:26
  • 1
    Yeah they really need to change those. – Adrian Larson May 7 '18 at 15:26

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.