Monday, 2 September 2019

Handling MIXED_DML_OPERATION Exception in Salesforce

you can easily run into this error if you are trying to perform DML on setup and non-setup objects in the  same transaction.

Non-Setup objects are standard objects like Account or any custom object.

Setup objects are Group1,GroupMember,QueueSObject,User2,UserRole, UserTerritory,Territory, etc..

ex :
you cannot insert an account and then insert a user or a group members in a single transaction.

1. Avoid MIXED_DML_OPERATION using system.runAs in test classes.

ex :

@isTest
static  void test_mixed_dmlbug() { 
    User u;
    Account a;     
    User thisUser = [ select Id from User where Id = :UserInfo.getUserId() ];
    System.runAs ( thisUser ) {
        Profile p = [select id from profile where name='(some profile)'];
        UserRole r = [Select id from userrole where name='(some role)'];
        u = new User(alias = 'standt', email='standarduser@testorg.com',
            emailencodingkey='UTF-8', lastname='Testing',
            languagelocalekey='en_US',
            localesidkey='en_US', profileid = p.Id, userroleid = r.Id,
            timezonesidkey='America/Los_Angeles',
            username='standarduser@testorg.com');
        a = new Account(Firstname='Terry', Lastname='Testperson');
        insert a;
    }
    System.runAs(u) {
        a.PersonEmail = 'test@madeupaddress.com';
        update a;
    }

}

2. Avoid MIXED_DML_OPERATION Exception by using Future Method.

ex : 

trigger Automatecontact on Account(after insert) {
     List<contact> lc = new List<contact>();

for (Account acc : Trigger.new) {
   lc.add( new contact(lastname ='dk',accountId =acc.id) );
}
insert lc;

UtilClass.userInsertWithRole('dineshd@outlook.com', 'Dinesh','dineshd@outlook.com', 'Dineshdk');

}
public class UtilClass {
  @future
  public static void userInsertWithRole(String uname, String al, String em, String lname)
   {
Profile p = [SELECT Id FROM Profile WHERE Name='Standard User'];
UserRole r = [SELECT Id FROM UserRole WHERE Name='COO'];
// Create new user with a non-null user role ID
User u = new User(alias = al, email=em,
emailencodingkey='UTF-8', lastname=lname,
languagelocalekey='en_US',
localesidkey='en_US', profileid = p.Id, userroleid = r.Id,
timezonesidkey='America/Los_Angeles',
username=uname);
insert u;
  }
 }



Note :

System.RunAs(User)

1.The system method runAs enables you to write test methods that change the user context to an existing user or a new user.

2.The original system context is started again after all runAs test methods complete.

No comments:

Post a Comment