You need to sign in to do that
Don't have an account?
Sharath Chikkanna
System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out
I'm getting this error while i'm running my test class. I have a webservice class which will send sms when i insert a new record or if i update a an existing record
Here are my webservice class, trigger which is invoking webservice call and test class for both class & trigger.
Web Service call
Trigger to invoke my webservice method
the above class and trigeer is for Account object and I have same kind of class and trigger for Debit Note also.
In my test class if i just insert account test method will be passed if i insert new debit note record along with account then i'm getting this callout exception
Error Message : System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out
Stack Trace : Class.CreatingAccountsendsms.Creating_Lead: line 50, column 1
Here is my test class
Here are my webservice class, trigger which is invoking webservice call and test class for both class & trigger.
Web Service call
public class CreatingAccountsendsms { @Future(callout=true) public static void Creating_Lead(string mobile,string leadname,string Uname,string UMobilePhone) { // list<account> acc=[SELECT Id,Phone FROM Account where id=:conId]; String Username ='management@abc.com'; String Password = '321@admin'; String TempID='21341'; String MobileNo=mobile; String SenderID = 'ABC'; String F1= leadname; String F3= Uname; String F2= UMobilePhone; String F4= ''; String postData = 'username=' +Username + '&pass=' + Password + '&dest_mobileno=' + MobileNo +'&senderid=' + SenderID + '&tempid=' + TempID+'&F1=' + F1+ '&F2=' + F2+ '&F3=' + F3+'&F4=' + F4; HttpRequest req = new HttpRequest(); req.setEndpoint('http://123.01.01.01/blank/sms/user/urlsmstemp.php?'+postdata); req.setMethod('GET'); system.debug(req); Http h = new Http(); HttpResponse res = h.send(req); //system.debug(res); //return res; } @Future(callout=true) public static void CreatingAccountsendsms1(string mobile,string leadname,string Uname,string UMobilePhone) { // list<account> acc=[SELECT Id,Phone FROM Account where id=:conId]; String Username ='management@ABC.com'; String Password = '321@admin'; String TempID='21342'; String MobileNo=mobile; String SenderID = 'ABC'; String F1= leadname; String F2= Uname; String F3= UMobilePhone; String F4= 'creatorname'; String postData = 'username=' +Username + '&pass=' + Password + '&dest_mobileno=' + MobileNo +'&senderid=' + SenderID + '&tempid=' + TempID+'&F1=' + F1+ '&F2=' + F2+ '&F3=' + F3+'&F4=' + F4; HttpRequest req = new HttpRequest(); req.setEndpoint('http://123.01.01.01/blank/sms/user/urlsmstemp.php?'+postdata); req.setMethod('GET'); system.debug(req); Http h = new Http(); HttpResponse res = h.send(req); //system.debug(res); //return res; } }
Trigger to invoke my webservice method
trigger sms on Account (after insert,after update) { for(Account acc:trigger.new) { user u=[SELECT Alias,Id,MobilePhone,Name,Phone,ProfileId FROM User where Id=:acc.OwnerId]; Profile p = [SELECT id,Name FROM Profile WHERE Id = :u.profileid]; system.debug('@@@@@@@@@+++++++++++++++++++++++++++++++++++++++++++++++++++++='+p.name); if(trigger.isafter){ CreatingAccountsendsms.Creating_Lead(acc.PersonMobilePhone,acc.Lastname,u.name,u.phone); } if(trigger.isupdate) { user u1=[SELECT Alias,Id,MobilePhone,Name,Phone FROM User where Id=:acc.CreatedById]; if(acc.ownerid != trigger.oldmap.get(acc.id).ownerid ) { if(p.name=='SPU - Sales Manager' || p.name=='Unishire Sales Profile' || p.name=='Channel Sales Manager') { system.debug('@@@@@@@@@+++++++++++++++++++++++++++++++++++++++++++++++++++++='+p.name); sendsms.sendsms1(u.MobilePhone,u.name,acc.Lastname,acc.PersonMobilePhone,acc.Project_Interested__c,u1.name); CreatingAccountsendsms.CreatingAccountsendsms1(acc.PersonMobilePhone,acc.Lastname,u.name,u.MobilePhone); //acc.name=u.Lastname; //sendsms.sendsms1(acc.Phone1__c,acc.name); } } } } }
the above class and trigeer is for Account object and I have same kind of class and trigger for Debit Note also.
In my test class if i just insert account test method will be passed if i insert new debit note record along with account then i'm getting this callout exception
Error Message : System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out
Stack Trace : Class.CreatingAccountsendsms.Creating_Lead: line 50, column 1
Here is my test class
@isTest(SeeAllData=true) public class new_test_class1{ @isTest static void Test_lead(){ Account acc= new Account(); acc.name='Acc1'; acc.Status__c='new'; acc.Custom_AN__c=1; acc.Project_Interested__c='atrium'; acc.Phone1__c='8015825819'; acc.Email__c='samdbinu@gmail.com'; insert acc; Debit_Note__c DN = new Debit_Note__c(); DN.Name = 'test'; DN.Account__c = acc.id; insert DN; Test.startTest(); Test.setMock(HttpCalloutMock.class, new Stubby()); string mobile = '12345'; string name = 'Sharat'; string status = 'done'; string dateon = '1/1/2014'; string Uname = 'New'; string Umobile = '90086573'; string leadname = 'Test'; string UMobilePhone = '90087345'; CreatingAccountsendsms.CreatingAccountsendsms1(mobile,leadname,Uname,UMobilePhone); Test.StopTest(); } }
I am providing you a answer in general, i hope this helps you to overcome the issue.
A Web Service Callout may not occur after a DML statement within the same transaction. To acheive the required action, the transaction must be separated into two parts so that the DML transaction is completed before the Web Service Callout occurs.
>> This workaround splits the transaction into two separate Ajax processes. The first inserts the record and the second performs the callout and is able to update the newly inserted record.
<!-- TestWsCallout.page -->
<apex:page controller="TestWsCallout" tabstyle="Account">
<apex:form >
<apex:actionFunction action="{!InsertRecord}" name="InsertRecord_JS" Rerender="statuses" status="Status1" oncomplete="CallWebService_JS();"/>
<apex:actionFunction action="{!CallWebService}" name="CallWebService_JS" status="Status2" reRender="statuses, msg"/>
<apex:outputPanel id="statuses">
<apex:actionStatus id="Status1" startText="...Inserting Record Into DB..." />
<apex:actionStatus id="Status2" startText="...Calling Web Service..." />
</apex:outputPanel>
<apex:outputPanel id="msg">
<apex:pageMessages />
</apex:outputPanel>
<div><input name="DoAction" class="btn" type="button" value="Do Action" onclick="InsertRecord_JS();return false;"/></div>
</apex:form>
</apex:page>
// TestWsCallout.cls
public class TestWsCallout{
Account myAccount;
public PageReference InsertRecord() {
myAccount = new Account(name = 'Test Account');
insert myAccount;
// Calling a Web Service here would throw an exception
return null;
}
public PageReference CallWebService() {
// Execute a call to a Web Service
HttpRequest req = new HttpRequest();
req.setEndpoint('http://MyWebService12345678790.com?id=' + myAccount.Id);
req.setMethod('GET');
HttpResponse response = new Http().send(req);
// Simulate an update
myAccount.Name = 'Test Account 2';
update myAccount;
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.CONFIRM, 'WebService Called on New Account: ' + myAccount.Name));
return null;
}
}
Thanks
Pramod