2

I'm getting an error and did some research on this error that I should not do DML operations before callouts. So how can I resolve the issue in my case?

I make two callouts in this class, I use the returned data of first call outs to create the master object records and than use the returned data of second callouts to create detail(child) object records.

If I separate this class to two classes, the DML operation will still have to be before the second callouts.

global class CE_GetSessions implements Queueable,Database.AllowsCallouts{

//key:sessionkeys
private Map<String,CE_Training_Session__c> sessions;
private List<CE_Training_Session__c> lstSessions;
private List<CE_Attendee_Infor__c> attendees;
public void execute(QueueableContext context){
    this.getSessionKeys();
    insert(lstSessions);
    System.debug(lstSessions);
    For(CE_Training_Session__c session : lstSessions)
    {
        sessions.put(session.Session_Key__c, session);
    }
    this.ProcessLiveAttendence();
    insert(attendees);
}

public CE_GetSessions() {
    sessions=new Map<String,CE_Training_Session__c>();
    attendees=new List<CE_Attendee_Infor__c>();
    lstSessions = new List<CE_Training_Session__c>();

}
//send request and get response of attendees information
//create and insert CE_Attendee_Infor__c (Attendee_Email__c,CE_Training_Session__c,Type_of_Attendence__c,Attendee__c)
void ProcessLiveAttendence()
{
    For(String sessionKey : sessions.keySet()){
        System.debug('sessionKey: '+sessionKey);
        HttpRequest req = new HttpRequest();
        req.setTimeout(120000);
        req.setMethod('POST');
        req.setEndpoint(endpoint);
        req.setHeader('Content-Type','text/xml' );
        req.setBody(CE_Utilities.getLstMeetingAttendeeXML(sessionKey));
        Http http = new Http();
        HttpResponse res = http.send(req);
        if(res.getStatusCode()==200)
        {
            dom.Document resDoc = res.getBodyDocument();
            dom.XmlNode root = resDoc.getRootElement();
            dom.XmlNode bodyElement = root.getChildElement('body', CE_Utilities.webexEndpoint);
            dom.XmlNode bodyContent = bodyElement.getChildElement('bodyContent',CE_Utilities.webexEndpoint);
            List<dom.XmlNode> historys = bodyContent.getChildElements();
            For(dom.XmlNode history : historys)
            {               

                dom.XmlNode attendeeEmailNode = history.getChildElement('attendeeEmail', CE_Utilities.historyEndpoint);
                if(attendeeEmailNode!=null)
                {           
                     String attendeeEmail=attendeeEmailNode.getText();                                                  
                     if(attendeeEmail!=null)
                     {
                         integer index1=attendeeEmail.indexOf('.');
                         integer index2=attendeeEmail.indexOf('@');
                         if(index1!=-1&&index2!=-1&&index1<index2)
                         {
                             CE_Attendee_Infor__c info = new CE_Attendee_Infor__c();
                             info.Attendee_Email__c=attendeeEmail;
                             String firstName=attendeeEmail.substring(0, index1);
                             String lastName=attendeeEmail.substring(index1+1, index2);                                  
                             String fullName=firstName+' '+lastName;
                             info.Attendee__c = CE_Utilities.ActiveUsers.get(fullName.toLowerCase());
                             info.CE_Training_Session__c=sessions.get(sessionKey).Id;
                             info.Type_of_Attendence__c='Live';  
                             if(info.Attendee__c!=null)
                             {
                                attendees.add(info);
                             }                              
                         }                             
                     }    
                }

            }


        }



    }   
}

//get the sessionkeys of live sessions that starts with "CE Sales"
//creates CE_Training_Session__c records
//Insert the session information as CE_Training_Session__c(Record_ID__c,Conf_Name__c,Duration__c,Session_Key__c,Start_Time__c,Time_Zone__c )
void getSessionKeys()
{
    System.debug('Entered getSessionKeys');    
    HttpRequest req = new HttpRequest();
    req.setMethod('POST');
    req.setEndpoint(endpoint);
    req.setHeader('Content-Type','text/xml' );
    req.setBody(CE_Utilities.getLsttrainingsessionHistoryXML(CE_Utilities.quarterStartString,CE_Utilities.quarterEndString));
    Http http = new Http();
    HttpResponse res = http.send(req);
    if(res.getStatusCode()==200)
    {
        dom.Document resDoc = res.getBodyDocument();
        dom.XmlNode root = resDoc.getRootElement();
        dom.XmlNode bodyElement = root.getChildElement('body', CE_Utilities.webexEndpoint);
        dom.XmlNode bodyContent = bodyElement.getChildElement('bodyContent',CE_Utilities.webexEndpoint);
        List<dom.XmlNode> historys = bodyContent.getChildElements();
        For(dom.XmlNode history : historys)
        {               
            dom.XmlNode confNameNode = history.getChildElement('confName', CE_Utilities.historyEndpoint);
            if(confNameNode!=null){
            String confName=confNameNode.getText();                    
            if(confName!=null&&confName.length()>=8&&confName.substring(0,8)=='CE Sales')
            {
                CE_Training_Session__c cts=new CE_Training_Session__c(Conf_Name__c=confName);               
                cts.Session_Key__c=history.getChildElement('sessionKey', CE_Utilities.historyEndpoint).getText();
                String startTime = history.getChildElement('sessionStartTime', CE_Utilities.historyEndpoint).getText();
                String stringDate = startTime.substring(6,10) + '-' + 
                startTime.substring(3,5) + '-' +
                startTime.substring(0,2) + ' ' +
                startTime.substring(11,19);
                cts.Start_Time__c=Datetime.valueOf(stringDate);
                String duration = history.getChildElement('duration', CE_Utilities.historyEndpoint).getText();
                cts.Duration__c = integer.valueof(duration);
                cts.Time_Zone__c = history.getChildElement('timeZoneWithDST', CE_Utilities.historyEndpoint).getText();
                lstSessions.Add(cts);
            }   }  



        }

    }
}    
}
1

If you do not need to do an insert of the session before the callout due to field or process requirements:

  1. you do not need the id
  2. the target system will not be calling in to get the records
  3. no workflow updates or formula values being used in the callout

then simply do the DML after the callout.

Otherwise, yes you will have to break it up

  • I tried to break it up and got another error: "Maximum callout depth has been reached." So it's the problem with chaining two callouts. Does this mean I have to run the two callouts separately and have two scheualble classes on for them? – sfdcnoob Jul 27 '15 at 22:31

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.