Thursday, December 10, 2015

System.LimitException: DML currently not allowed

Whenever we trying to perform any DML operations at the time of initial page load we will be ending up with an error called System.LimitException: DML currently not allowed. In this post I am going to show how to produce the issue with simple example and workaround for the same issue.

1.Create simple page and class as shown below

VF Page Name : DeleteAllConts
 <apex:page controller="DeleteAllContCtrl">  
 </apex:page>  

Controller
1:  public class DeleteAllContCtrl  
2:  {  
3:   public DeleteAllContCtrl()  
4:   {  
5:    Id AccId = Apexpages.CurrentPage().getParameters().get('id');    
6:    Delete ([SELECT id FROM Contact WHERE AccountID=:AccId]);  
7:   }  
8:  }  

Now create a simple page with hyperlink and run it by passing any AccountID
1:  <apex:page standardController="Account">  
2:        <apex:outputLink value="/apex/DeleteAllConts?id={!Account.id}"> Delete All Contacts</apex:outputLink>   
3:  </apex:page>  

When user clicks on link it will be calling the DeleteAllConts page by passing the current AccountID as parameter.Once the execution starts at the controller it will be throwing an error System.LimitException: DML currently not allowed at delete statement(line number 6) in DeleteAllContCtrl class.

Reason for the Error:
1.When you are trying invoke any controller from visual force page to perform any dml operations (insert/delete/update/upsert) inside the constructor or any method called from constructor it will not allowed.
2.Within a single transaction - Web Service callouts just after the DML operation.(Thanks for Girish for providing this point)

Workaround for solutions 

1. Move the dml statements out of the constructor
2.Create a method place that dml operations inside that method and invoke that method directly from page using the action attribute in <apex:page> tag

Modified DeleteAllConts Page and Controller

 <apex:page controller="DeleteAllContCtrl" action="{!delContacts}">  
 </apex:page>  

1:  public class DeleteAllContCtrl  
2:  {  
3:   public DeleteAllContCtrl()  
4:   {  
5:    System.debug('Eneterd Inside Contsructor');  
6:   }  
7:   public void delContacts()  
8:   {  
9:    Id AccId = Apexpages.CurrentPage().getParameters().get('id');    
10:    Delete ([SELECT id FROM Contact WHERE AccountID=:AccId]);  
11:   }  
12:  }  

Thanks for visiting....Enjoy.....

No comments: