how to solve callout error? You have uncommitted work pending. Please commit or rollback before calling out

  • I have written inline Vf page to update the record value. The values are coming from a web service. While updating the record the detail page redirected to VF page. But the record was committed in the database with the error in debug log

    "You have uncommitted work pending. Please commit or rollback before calling out"

    I want to save the value in the record and the page remains in the same detail page. How could I achieve this?

    controller:

    public with sharing class  ServiceOptionsChange_CLS{ 
    
    public string strId;
    public String strOppid{get;set;}
    public String strModelCode {get;set;}
    public String strVersionCode {get;set;}
    public List<SelectOption> lstOptions {get; private set;}
    List<String> lstC2Goptions= new List<String>();
    public String strop{get;set;}
    public Service__c objService{get;set;}
    public boolean refreshPage{get;set;}
    public String strCode {get;set;}
    public String strLabel {get;set;}
    public Map<String,Double> mapOptionCodePrice = new Map<String,Double>();
    
    public ServiceOptionsChange_CLS(ApexPages.StandardController controller) {
        objService = new Service__c();
        strId=ApexPages.currentPage().getParameters().get('id');
        Service__c objService=[select Opportunity_car_set__c from Service__c where id=:strId]; 
        strOppid=objService.Opportunity_car_set__c; 
        Opportunity_car_set__c opp=[SELECT Model__r.ProductCode,Version__r.version_code__c,Country_Code__c FROM Opportunity_car_set__c where id=:strOppid];    
        strModelCode    = opp.Model__r.ProductCode;
        strVersionCode  = opp.Version__r.version_code__c;
        system.debug('<<<<<selected value'+strModelCode+''+strVersionCode);
    
      } 
    
    
    public List<SelectOption> getOptions(){
    
       OptionDetails_CLS optionValue=new OptionDetails_CLS();
        if(String.isNotBlank(strModelCode) && String.isNotBlank(strVersionCode)){
            lstC2Goptions=optionValue.getPriceListbasedOnReference(strModelCode,strVersionCode);
       }
        if(lstC2Goptions.size()>0){
            lstOptions = new List<SelectOption>();
            lstOptions.add(new SelectOption('','--Select--'));
            for(String strC2Goptions:lstC2Goptions) {
                lstOptions .add(new SelectOption(strC2Goptions,strC2Goptions));
            }
        }
      return lstOptions ;
    }
    
    
    public Pagereference customSave(){
    
        strop=objService.CodeC2G__c;
        String strQuantity=String.valueof(objService.Quantity__c);
        system.debug('<<<<<selected value in save'+strop+'quanity'+strQuantity);
        strCode=strop.substringbefore('-').trim();
        strLabel =strop.substringafter('-').trim();
        system.debug('<<<<<strCode'+strCode+''+strLabel);
        objService.id=strId;
        objService.Code__c=strCode;
        objService.Label__c=strLabel;
        Double dbPriceHT;
        OptionDetails_CLS optionValues =new OptionDetails_CLS();     
        mapOptionCodePrice = optionValues.getOptionPrice(strModelCode,strVersionCode);
        if (mapOptionCodePrice.containsKey(strCode)) {
            dbPriceHT = mapOptionCodePrice.get(strCode);
        }
        if (dbPriceHT!=null) {
            objService.Price_HT__c=dbPriceHT;
        }
    
        try{
            update objService;
            refreshPage=true;
            system.debug('<<<<<objService up'+objService);
            return null;
        }
        catch(Exception ex){
            System.debug('Error in SOQL Fetching'+ex);
            ApexPages.Message msg = new ApexPages.Message(Apexpages.Severity.ERROR, ex.getMessage() );
            ApexPages.addMessage(msg);
           return null;
            }
    }
    
     }
    

    vf:

    <apex:page standardController="Service__c" extensions="ServiceOptionsChange_CLS" sidebar="true" >
    <apex:form >
    <apex:pageBlock >
    <apex:pageblockbuttons location="bottom">
    <apex:commandbutton value="Save" action="{!customSave}" /> 
    </apex:pageblockbuttons> <apex:pageblocksection columns="2" title="Main Information" >
    <apex:selectList size="1" value="{!objService.CodeC2G__c}" >
    <apex:selectOptions value="{!Options }" > </apex:selectOptions>
    <apex:actionSupport event="onchange" action="{!customSave}" reRender="a" />
    </apex:selectList>
    <br></br>
    <apex:inputfield value="{!objService.Quantity__c}" required="false" />
    <apex:pageblocksectionitem />
    </apex:pageblocksection>
    </apex:pageBlock>
    </apex:form>
    </apex:page>
    

    That error is because you can't callout after DML, you need to do a callout first or put it in a @future method. It is not very clear where are you doing your callout here, you can refer to this post for more info on the error http://salesforce.stackexchange.com/questions/41440/system-calloutexception-you-have-uncommitted-work-pending

  • Ratan Paul

    Ratan Paul Correct answer

    5 years ago

    The issue occurs when you first perform DML and then callout in the same transaction

    check this doc

    You have uncommitted work pending. Please commit or rollback before calling out

    You need to perform Callout in the future method so your callout and DML will be in the different transaction

    This way you can resolve this issue

    create a list and serialize it to pass to the future method. Because we can't pas list of sobject as a parameter in the future method

    insert listofAccount;
    
    string jsonString = JSON.serializePretty(listofAccount );
    
    callout(jsonString);
    

    In future method make callout

    @future(callout = true)
    public static void callout(string jsonString){
        //do callout here rest or soap
    }
    

    this way you can solve this issue.

    Actually, the documentation linked to in this answer explains that the "Web Service Callout may not occur after a DML statement". So the issue is caused by executing DML prior to the callout, not after. The author of the answer has it backwards.

    @SF1Dev thanks for bringing in my notice. Updated answer now

License under CC-BY-SA with attribution


Content dated before 7/24/2021 11:53 AM