function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Roshan singh 21Roshan singh 21 

I am getting an error when fetching data from the third-party system using rest API."Too many query rows: 50001"

Hi All,

I am getting an error when fetching data from the third-party system using rest API.
Too many query rows: 50001
Error is in expression '{!saveCalloutResult}' in component <apex:commandButton> in page issuercallvfpage: Class.Database.QueryLocatorIterator.hasNext: line 41, column 1
Class.RestapiCallclass.saveCalloutResult: line 66, column 1
Class.RestapiCallclass.saveCalloutResult: line 16, column 1


My code:- 

public class RestapiCallclass {

    public void saveCalloutResult(){
        string[] urllist = new List<String>();
        urllist.add('https://preview.test1.com/ifsservice/issuer/getIssueList');
        urllist.add('https://preview.test2.com/ifsservice/issuer/getIssueList');
        urllist.add('https://preview.test3.com/ifsservice/issuer/getIssueList');
        urllist.add('https://preview.test4.com/ifsservice/issuer/getIssueList');
        urllist.add('https://preview.test5.com/ifsservice/issuer/getIssueList');
        
        for( Integer i=0; i< urllist.size(); i++ ){
        saveCalloutResult(urllist[i]);
        }
        }
     
    public void saveCalloutResult(string url){
         // Instantiate a new http object
        Http h = new Http();
        HttpRequest req = new HttpRequest();
        req.setEndpoint(url);
        req.setMethod('GET');
        req.setHeader('Content-Type', 'application/json');
        req.setHeader('Accept','application/json');
         system.debug('### '+ req);    
        String username = 'username';
        String password = 'password';
        
        Blob headerValue= Blob.valueOf(username + ':' + password);
        String authorizationHeader = 'Basic ' + EncodingUtil.base64Encode(headerValue);
        req.setHeader('Authorization', authorizationHeader);
        
        system.debug('###req### '+ req);            
        HttpResponse res = h.send(req);
        system.debug('###res### '+ res);
        
        string response = res.getBody();
        system.debug('### '+ response);
               
        List<JsonParserDetail> responseDetails = JsonParserDetail.parse(response); 
        system.debug('### '+responseDetails);
        
        Set<String> bankNames = New Set<String>();
        // declare issuer list to inser 
        List<Issuer__c> InsertedIssuers = New List<Issuer__c>();
        // I used limit in below query, but its better to use any filter to limit the data
        for(Issuer__c issuer : [Select Id,Bankdir_Name__c from Issuer__c LIMIT 50000]){
            If(!string.isBlank(issuer.Bankdir_Name__c)){
                bankNames.add(issuer.Bankdir_Name__c);
            }
        }
        
        if(responseDetails.size() > 0){
            for(JsonParserDetail jpd : responseDetails){
                If(! bankNames.contains(jpd.issuerBankdirName)){
                    InsertedIssuers.add(getIssuer(jpd.issuername,jpd.issuerBankdirName,jpd.processorName,jpd.subProcessorName,jpd.siloName));
                }
            }
        }
        If(InsertedIssuers.size() >0){
            insert InsertedIssuers;
        }
    }
    
    public Issuer__c getIssuer(string iName, string ibName, string pName, string spName,string siloName){
        Issuer__c issuer = New Issuer__c();
        issuer.Name = iName;
        issuer.Bankdir_Name__c = ibName;
        issuer.Processor_Name__c = pName;
        issuer.SubProcessor_Name__c = spName;
        issuer.Silo_Name__c = siloName;
        return issuer;
    }
}

Visual force page:- 
<apex:page controller="RestapiCallclass " sidebar="True"> <apex:form > <apex:commandButton value="Refresh Issuer List from Server" action="{!saveCalloutResult}"/> </apex:form> </apex:page>


Please help me how I will resolve this error using the following code.
Thanks in Advance. 
PawanKumarPawanKumar
The only way to use batch Apex that's what I can see to overcome 50000 limits/ add criteria in a query to narrow down count. 
Roshan singh 21Roshan singh 21
Thank you so much, Pawan
Can you help me how to use batch apex in this code?
please provide me sample code for this 

 
 
PawanKumarPawanKumar
Please modified code here. Please handle any typo error.

public class RestapiCallclass {

    public void saveCalloutResult(){
        string[] urllist = new List<String>();
        urllist.add('https://preview.test1.com/ifsservice/issuer/getIssueList');
        urllist.add('https://preview.test2.com/ifsservice/issuer/getIssueList');
        urllist.add('https://preview.test3.com/ifsservice/issuer/getIssueList');
        urllist.add('https://preview.test4.com/ifsservice/issuer/getIssueList');
        urllist.add('https://preview.test5.com/ifsservice/issuer/getIssueList');
        
        for( Integer i=0; i< urllist.size(); i++ ){
        saveCalloutResult(urllist[i]);
        }
        }
     
    public void saveCalloutResult(string url){
         // Instantiate a new http object
        Http h = new Http();
        HttpRequest req = new HttpRequest();
        req.setEndpoint(url);
        req.setMethod('GET');
        req.setHeader('Content-Type', 'application/json');
        req.setHeader('Accept','application/json');
         system.debug('### '+ req);    
        String username = 'username';
        String password = 'password';
        
        Blob headerValue= Blob.valueOf(username + ':' + password);
        String authorizationHeader = 'Basic ' + EncodingUtil.base64Encode(headerValue);
        req.setHeader('Authorization', authorizationHeader);
        
        system.debug('###req### '+ req);            
        HttpResponse res = h.send(req);
        system.debug('###res### '+ res);
        
        string response = res.getBody();
        system.debug('### '+ response);
               
        List<JsonParserDetail> responseDetails = JsonParserDetail.parse(response); 
        system.debug('### '+responseDetails);
        
        String query = 'Select Id,Bankdir_Name__c from Issuer__c';
        ProcessIssuerBatch processBatch = new ProcessIssuerBatch(query,responseDetails);
        Database.executeBatch(processBatch,2000);

    }

}


Batch code
----------------------------


global class ProcessIssuerBatch implements Database.Batchable<sObject> {
    global List<JsonParserDetail> responseDetails;
    global String query;
    
    global ProcessIssuerBatch(String query,List<JsonParserDetail> responseDetails){
        this.query = query;
        this.responseDetails=responseDetails;
    }
    
    global Database.QueryLocator start(Database.BatchableContext BC) {
        return Database.getQueryLocator(query);
    }
     
    global void execute(Database.BatchableContext BC, List<Issuer__c> issuerList) {
        
        // process each batch of records
        Set<String> bankNames = New Set<String>();
        List<Issuer__c> InsertedIssuers = New List<Issuer__c>();
        for(Issuer__c eachIssuer : issuerList)
        {        
            If(!string.isBlank(eachIssuer.Bankdir_Name__c)){
                bankNames.add(eachIssuer.Bankdir_Name__c);
            }
            
            
        }
        
        if(responseDetails.size() > 0){
            for(JsonParserDetail jpd : responseDetails){
                If(! bankNames.contains(jpd.issuerBankdirName)){
                    InsertedIssuers.add(getIssuer(jpd.issuername,jpd.issuerBankdirName,jpd.processorName,jpd.subProcessorName,jpd.siloName));
                }
            }
        }
        
        try{
            If(InsertedIssuers.size() >0){
                insert InsertedIssuers;
            }
        } catch(Exception e) {
            System.debug(e);
        }
         
    }   
     
    global void finish(Database.BatchableContext BC) {
            AsyncApexJob a = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed,
            TotalJobItems, CreatedBy.Email
            FROM AsyncApexJob WHERE Id =
            :BC.getJobId()];
            
            // Send an email to the Apex job's submitter notifying of job completion.
            Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
            String[] toAddresses = new String[] {a.CreatedBy.Email};
            mail.setToAddresses(toAddresses);
            mail.setSubject('ProcessIssuerBatch Completed ' + a.Status);
            mail.setPlainTextBody
            ('The batch Apex job processed ' + a.TotalJobItems +
            ' batches with '+ a.NumberOfErrors + ' failures.');
            Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
    }
  
   // -- utility method
   global Issuer__c getIssuer(string iName, string ibName, string pName, string spName,string siloName){
        Issuer__c issuer = New Issuer__c();
        issuer.Name = iName;
        issuer.Bankdir_Name__c = ibName;
        issuer.Processor_Name__c = pName;
        issuer.SubProcessor_Name__c = spName;
        issuer.Silo_Name__c = siloName;
        return issuer;
    }
}

Please mark it best if it helps you. Thanks.

Regards,
Pawan Kumar
 
PawanKumarPawanKumar
Please let me know if it works for you. Thanks.
Roshan singh 21Roshan singh 21
Hi Pawan,
Thank you so much.
 Now I am getting this error kindly help me. 

You have uncommitted work pending. Please commit or rollback before calling out
Error is in expression '{!saveCalloutResult}' in component <apex:commandButton> in page issuercallvfpage: Class.detailParserCallout.saveCalloutResult: line 36, column 1
Class.detailParserCallout.saveCalloutResult: line 14, column 1
 
PawanKumarPawanKumar
please change the below loop. You just pass list to method and handle this loop inside saveCalloutResult.

for( Integer i=0; i< urllist.size(); i++ ){
        saveCalloutResult(urllist[i]);
        }

aveCalloutResult(urllist);
 
PawanKumarPawanKumar
I mean please try below and let me know.

    
public void saveCalloutResult(){
        string[] urllist = new List<String>();
        urllist.add('https://preview.test1.com/ifsservice/issuer/getIssueList');
        urllist.add('https://preview.test2.com/ifsservice/issuer/getIssueList');
        urllist.add('https://preview.test3.com/ifsservice/issuer/getIssueList');
        urllist.add('https://preview.test4.com/ifsservice/issuer/getIssueList');
        urllist.add('https://preview.test5.com/ifsservice/issuer/getIssueList');
        
        saveCalloutResult(urllist);
        }
     
     public void saveCalloutResult(string string[] urllist){
        List<JsonParserDetail> responseDetails = new List<JsonParserDetail>();
        List<JsonParserDetail> responseDetailstemp;
         for( Integer i=0; i< urllist.size(); i++ ){
            // Instantiate a new http object

            Http h = new Http();
            HttpRequest req = new HttpRequest();
            req.setEndpoint(urllist[i]);
            req.setMethod('GET');
            req.setHeader('Content-Type', 'application/json');
            req.setHeader('Accept','application/json');
            system.debug('### '+ req);    
            String username = 'username';
            String password = 'password';
            
            Blob headerValue= Blob.valueOf(username + ':' + password);
            String authorizationHeader = 'Basic ' + EncodingUtil.base64Encode(headerValue);
            req.setHeader('Authorization', authorizationHeader);
            
            system.debug('###req### '+ req);            
            HttpResponse res = h.send(req);
            system.debug('###res### '+ res);
            
            string response = res.getBody();
            system.debug('### '+ response);
                   
            responseDetailstemp = JsonParserDetail.parse(response); 
            system.debug('### '+responseDetailstemp);
            
            for(JsonParserDetail eachParserDetail:responseDetailstemp){
                responseDetails.add(eachParserDetail);
            }
        }
        
        String query = 'Select Id,Bankdir_Name__c from Issuer__c';
        ProcessIssuerBatch processBatch = new ProcessIssuerBatch(query,responseDetails);
        Database.executeBatch(processBatch,2000);
    }

}    
 
Roshan singh 21Roshan singh 21
Hi Pawan,

When I am trying to save ProcessIssuerBatch class that time i got this error,

Error: Compile Error: global methods do not support parameter type of List<JsonParserDetail> at line 6 column 11

for removing this error I  changed in line no 6  global to Public and after that, I checked when i am clicking a button on visualpage then it not creating record form the sever in salesforce. 



Batch code
----------------------------

global class ProcessIssuerBatch implements Database.Batchable<sObject> {
    global List<JsonParserDetail> responseDetails;
    global String query;
    
    Public  ProcessIssuerBatch(String query,List<JsonParserDetail> responseDetails){
        this.query = query;
        this.responseDetails=responseDetails;
    }
    
    global Database.QueryLocator start(Database.BatchableContext BC) {
        return Database.getQueryLocator(query);
    }
     
    global void execute(Database.BatchableContext BC, List<Issuer__c> issuerList) {
        
        // process each batch of records
        Set<String> bankNames = New Set<String>();
        List<Issuer__c> InsertedIssuers = New List<Issuer__c>();
        for(Issuer__c eachIssuer : issuerList)
        {        
            If(!string.isBlank(eachIssuer.Bankdir_Name__c)){
                bankNames.add(eachIssuer.Bankdir_Name__c);
            }
            
            
        }
        
        if(responseDetails.size() > 0){
            for(JsonParserDetail jpd : responseDetails){
                If(! bankNames.contains(jpd.issuerBankdirName)){
                    InsertedIssuers.add(getIssuer(jpd.issuername,jpd.issuerBankdirName,jpd.processorName,jpd.subProcessorName,jpd.siloName));
                }
            }
        }
        
        try{
            If(InsertedIssuers.size() >0){
                insert InsertedIssuers;
            }
        } catch(Exception e) {
            System.debug(e);
        }
         
    }   
     
    global void finish(Database.BatchableContext BC) {
            AsyncApexJob a = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed,
            TotalJobItems, CreatedBy.Email
            FROM AsyncApexJob WHERE Id =
            :BC.getJobId()];
            
            // Send an email to the Apex job's submitter notifying of job completion.
            Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
            String[] toAddresses = new String[] {a.CreatedBy.Email};
            mail.setToAddresses(toAddresses);
            mail.setSubject('ProcessIssuerBatch Completed ' + a.Status);
            mail.setPlainTextBody
            ('The batch Apex job processed ' + a.TotalJobItems +
            ' batches with '+ a.NumberOfErrors + ' failures.');
            Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
    }
  
   // -- utility method
   global Issuer__c getIssuer(string iName, string ibName, string pName, string spName,string siloName){
        Issuer__c issuer = New Issuer__c();
        issuer.Name = iName;
        issuer.Bankdir_Name__c = ibName;
        issuer.Processor_Name__c = pName;
        issuer.SubProcessor_Name__c = spName;
        issuer.Silo_Name__c = siloName;
        return issuer;
    }
}


 
PawanKumarPawanKumar
Please check after sometimes and see records get created or not?

If not created can you please let me know the received email contents after batch completion
Roshan singh 21Roshan singh 21

Hi Pawan, 
Records are not creating.

Please find my complete code below and let me know where I am doing a mistake.
Controller

public class RestapiCallclass {

   public void saveCalloutResult(){
        string[] urllist = new List<String>();
        urllist.add('https://preview.test1.com/ifsservice/issuer/getIssueList');
        urllist.add('https://preview.test2.com/ifsservice/issuer/getIssueList');
        urllist.add('https://preview.test3.com/ifsservice/issuer/getIssueList');
        urllist.add('https://preview.test4.com/ifsservice/issuer/getIssueList');
        urllist.add('https://preview.test5.com/ifsservice/issuer/getIssueList');
        
        saveCalloutResult(urllist);
        }
     
     public void saveCalloutResult( string[] urllist){
        List<JsonParserDetail> responseDetails = new List<JsonParserDetail>();
        List<JsonParserDetail> responseDetailstemp;
         for( Integer i=0; i< urllist.size(); i++ ){
            // Instantiate a new http object
            Http h = new Http();
            HttpRequest req = new HttpRequest();
            req.setEndpoint(urllist[i]);
            req.setMethod('GET');
            req.setHeader('Content-Type', 'application/json');
            req.setHeader('Accept','application/json');
            system.debug('### '+ req);    
            String username = 'username';
            String password = 'password';
            
            Blob headerValue= Blob.valueOf(username + ':' + password);
            String authorizationHeader = 'Basic ' + EncodingUtil.base64Encode(headerValue);
            req.setHeader('Authorization', authorizationHeader);
            
            system.debug('###req### '+ req);            
            HttpResponse res = h.send(req);
            system.debug('###res### '+ res);
            
            string response = res.getBody();
            system.debug('### '+ response);
                   
            responseDetailstemp = JsonParserDetail.parse(response); 
            system.debug('### '+responseDetailstemp);
            
            for(JsonParserDetail eachParserDetail:responseDetailstemp){
                responseDetails.add(eachParserDetail);
            }
        }
        
        String query = 'Select Id,Bankdir_Name__c from Issuer__c';
        ProcessIssuerBatch processBatch = new ProcessIssuerBatch(query,responseDetails);
        Database.executeBatch(processBatch,2000);
    }

}    
 please help me