+ Start a Discussion
nagendra kumar 21nagendra kumar 21 

MIXED_DML_OPERATION, DML operation Invalid Data. System.DmlException

hello All, 

I have created a custom user history object to store the old and new value for the updates or changes made in the user object.
my code is working for first and last name fields but not for all other fields and getting this error "

Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger UserTrigger caused an unexpected exception, contact your administrator: UserTrigger: execution of AfterUpdate caused by: System.DmlException: In
apex code - 



public class UserTriggerHandler {
    public static void onAfterUpdate (List<User> userList, Map<Id, User> oldUserMap){
        CreateUserHistoryRecords(userList,oldUserMap);
    }
    
    public static void CreateUserHistoryRecords(List<User> userList, Map<Id, User> oldUserMap){
       List<string> fieldList = new List<String> ();
        List<Schema.FieldSetMember> fieldSetMemberList =  readFieldSet('User_History_Fields','User');
        for(Schema.FieldSetMember fieldSetMemberObj : fieldSetMemberList)
        {
            fieldList.add(fieldSetMemberObj.getFieldPath());
            
        } 
    List<User_History__c> userHistoryRecords = new List<User_History__c>();
        for(User newrec : userList){
            User oldrec = oldUserMap.get(newrec.Id);
            for(String FieldName : fieldList){
                if(oldrec.get(FieldName)!=newrec.get(FieldName)){
                  
                    User_History__c uhrec = new User_History__c();
                    uhrec.Field__c = FieldName;
                    uhrec.NewValue__c =(String)newrec.get(FieldName);
                    uhrec.OldValue__c = (String)oldrec.get(FieldName);
                    uhrec.User_ID__c = newrec.Id;
                    userHistoryRecords.add(uhrec);            
                }
            }
        }
        if(!userHistoryRecords.isEmpty())
        {
            insert userHistoryRecords;
    }
    }
    
     public static List<Schema.FieldSetMember> readFieldSet(String fieldSetName, String ObjectName)
    {
        System.debug(fieldSetName);
        System.debug(ObjectName);
        Map<String, Schema.SObjectType> GlobalDescribeMap = Schema.getGlobalDescribe(); 
        Schema.SObjectType SObjectTypeObj = GlobalDescribeMap.get(ObjectName);
        Schema.DescribeSObjectResult DescribeSObjectResultObj = SObjectTypeObj.getDescribe();
        
        system.debug('====>' + DescribeSObjectResultObj.FieldSets.getMap());
        
        Schema.FieldSet fieldSetObj = DescribeSObjectResultObj.FieldSets.getMap().get(fieldSetName);
        
        //List<Schema.FieldSetMember> fieldSetMemberList =  fieldSetObj.getFields();
        //system.debug('fieldSetMemberList ====>' + fieldSetMemberList);  
        if(fieldSetObj!=null){
            return fieldSetObj.getFields(); 
        }
        else{
            return null;
        }
    }  
    
}






Trigger - 

1
2
3
4
5
6
7
8
9
trigger UserTrigger on User (after update) {
    
    if ( trigger.isAfter ) {
        if ( trigger.isUpdate ) {
            UserTriggerHandler.onAfterUpdate(trigger.new, trigger.oldMap);
        }
    }
    
}

sert failed. First exception on row 0; first error: MIXED_DML_OPERATION, DML operation on setup object is not permitted after you have updated a non-setup object (or vice versa): User_History__c, original object: User: []: Class.UserTriggerHandler.CreateUserHistoryRecords: line 31, column 1
can anyone please check and let me know where to change 
Maharajan CMaharajan C
Hi Nagendra,

Update the your apex method as Future then you will not see the Mixed DML error. 
@future
public static void onAfterUpdate (List<User> userList, Map<Id, User> oldUserMap){
        CreateUserHistoryRecords(userList,oldUserMap);
    }
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_dml_non_mix_sobjects.htm
https://www.xgeek.net/salesforce/to-fix-mixed_dml_operation-errorsetup-and-non-setup-objects-in-salesforce/

Thanks,
Maharajan.C
Maharajan CMaharajan C
The issue is User is a setup object and you can not insert a non-setup object records in the same transaction. so you have to do this asynchronously.