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.
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