2

enter image description hereAn apex method that returns a continuation object can’t perform DML. The solution given by the Salesforce developer documentation is the “perform DML operations in the Apex callback method”. https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/apex_continuations_limits.htm

I tried to do DML operations in the Apex callback method in new Continuation approach. But it was not working. Continuation was failed. It gave below error. What should I do for this? Debug log of the error

public with sharing class newContinuation1 {
    private static final String LONG_RUNNING_SERVICE_URL =
        'http://dummy.restapiexample.com/api/v1/employees';
    public static List<String> requestLabel;
    public static String result; 

    @AuraEnabled(continuation=true cacheable=false)
    public static Object getstartRequest() {
        Continuation con = new Continuation(40);
        con.continuationMethod='processResponse';
        con.state='SUCCESS';
        HttpRequest req = new HttpRequest();
        req.setMethod('GET');
        req.setEndpoint(LONG_RUNNING_SERVICE_URL);
        con.addHttpRequest(req);        
        return con;
    }

    @AuraEnabled(cacheable=false)
    public static Object processResponse(List<String> labels, Object state) {

        HttpResponse response = Continuation.getResponse(labels[0]);

        String result = response.getBody();
        Account acct1 = new Account(Name='samushika333');
        try
        {
            insert acct1;
            return result;
        } catch (DmlException e) {
            System.debug('Exception'+e);
            return result;
        }

    }

}
8
  • Is your aura method have `cacheable=true? Commented Jul 2, 2019 at 10:19
  • I did DML operation with and without @AuraEnabled (Cacheable=true) annotation. but it failed in both cases.
    – R_Cham
    Commented Jul 2, 2019 at 13:01
  • Is it Aura or LWC? Cause in aura if you set setCacheable as true we get same exception Commented Jul 2, 2019 at 13:31
  • Yes. I added both screenshot and the code to the original post.
    – R_Cham
    Commented Jul 2, 2019 at 13:43
  • This is Aura. can't we do DML operation within the callback method?
    – R_Cham
    Commented Jul 2, 2019 at 13:45

2 Answers 2

2

I found a working solution for doing DML from a continuation method. According to the documentation for Continuation Limits,

An Apex method that returns a Continuation object can’t perform Data Manipulation Language (DML) operations.

What I did to get DML to work from a continuation call was to execute another apex method in the same Javascript method that the Apex action / continuation call originated. To get the records that I need to perform DML manipulation on, I just passed the data that was return from the continuation method to the apex method that handles DML.

Here the Javascript class method:

import startRequest from '@salesforce/apexContinuation/CalloutHandler.startRequest';
import insertRecords from '@salesforce/apex/CalloutHandler.insertRecords';

    startRequest() {

        this.loaded = true;
        this.result = '';

        startRequest({objId: this.recordId, someId: this.Some_Id__c})
            .then(result => {

                this.result = result;
                var parsedVal = JSON.parse(result);

                this.sObjectWrapperData = parsedVal.sObjectWrapperData;
                insertRecords({Data: JSON.stringify(this.sObjectWrapperData)});

                this.loaded = false;

            })
            .catch(error => {
                this.error = error;
            });

    }

This is the Apex class methods:

/*
 * Continuation method for POST request
 * */
@AuraEnabled(cacheable=true)
public static Object processResponse(List<String> labels) {

    Wrapper.ResponseWrapper Response = new Wrapper.ResponseWrapper();
    HttpResponse response = Continuation.getResponse(labels[0]);

    if(response.getBody() != null && response.getStatusCode() == 200) {
        Response.sObjectWrapperData = (Wrapper.sObjectWrapper)json.deserialize(response.getBody(),Wrapper.sObjectWrapper.class);
    }

    return json.serialize(Response);
}

/*
 * Method for handling all DML operations data
 * */
@AuraEnabled
public static String insertRecords(String Data) {

    Wrapper.ResponseWrapper Response = new Wrapper.ResponseWrapper();
    Response.sObjectWrapperData = (Wrapper.sObjectWrapper)json.deserialize(Data, Wrapper.sObjectWrapper.class);

    // List of Opportunity records to be updated or inserted.
    List<Opportunity> oppToUpsert = new List<Opportunity>();

            Opportunity o = new Opportunity();
            o.Name = 'Some Name';
            o.AccountId = 'someaccountID';
            o.CloseDate = date.today();
        }
    }

    if (!oppToUpsert .isEmpty())
        Database.upsert(oppToUpsert , false);

    return null;
}
1

We had the same issue for an LWC we had created, turned out it was not due to the Continuation it was because we had used the @wire service to make the call. I am guessing the @wire service forces Cacheable on which bans DMLs.

Solution, we changed the calling point to be in the connectedCallback and it allowed the DML.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .