Mixed DML Operation Error in Salesforce?

Mixed DML Operation Error in Salesforce?

On April 4, 2025, Posted by , In Apex, With Comments Off on Mixed DML Operation Error in Salesforce?

Question:

I am encountering a MIXED_DML_OPERATION error when trying to perform DML operations on setup objects (e.g., Custom Settings) and non-setup objects (e.g., Lead) in the same transaction.
Here’s a snippet of my test class:

Group g1 = new Group(Name = 'group name', Type = 'Queue');
insert g1;

QueueSObject q1 = new QueueSObject(QueueID = g1.Id, SobjectType = 'Lead');
insert q1;

SetOwner__c mycs = SetOwner__c.getValues('standardset');
if (mycs == null) {             
    mycs = new SetOwner__c(Name = 'CustomValues');
    mycs.OwnerId__c = '00520000000z3PrAAI';
    mycs.RecordtypeID__c = '012L00000004QsrIAE';
    insert mycs; // Setup object DML
}

Lead lead = createNewLead(u2.Id);
insert lead; // Non-setup object DML

When running this code, I receive the following error:

MIXED_DML_OPERATION, DML operation on setup object is not permitted after you have updated a non-setup object (or vice versa): SetOwner__c, original object: QueueSObject

How can I resolve this issue in both test and non-test scenarios?

Answer:

The MIXED_DML_OPERATION error occurs because Salesforce enforces restrictions on performing DML operations on setup and non-setup objects in the same transaction. Here are two solutions for handling this issue, depending on the context.

Boost your Salesforce career with top-notch Salesforce training in Delhi, offering hands-on projects and expert guidance for both beginners and professionals.

Solution 1: Using System.runAs in Test Classes

In test classes, you can use the System.runAs method to separate the DML operations into different user contexts. Here’s how to modify your test class to resolve the issue:

@isTest
public class MixedDmlTest {
    static testMethod void testMixedDml() {
        User testUser = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId() LIMIT 1];

        // Perform DML on setup objects within System.runAs
        System.runAs(testUser) {
            SetOwner__c mycs = SetOwner__c.getValues('standardset');
            if (mycs == null) {             
                mycs = new SetOwner__c(Name = 'CustomValues');
                mycs.OwnerId__c = '00520000000z3PrAAI';
                mycs.RecordtypeID__c = '012L00000004QsrIAE';
                insert mycs;
            }
        }

        // Perform DML on non-setup objects
        Group g1 = new Group(Name = 'group name', Type = 'Queue');
        insert g1;

        QueueSObject q1 = new QueueSObject(QueueID = g1.Id, SobjectType = 'Lead');
        insert q1;

        Lead lead = createNewLead(testUser.Id);
        insert lead;
    }
}

Code explanation:
The provided code demonstrates how to handle a MIXED_DML_OPERATION error in a test class by separating DML operations on setup and non-setup objects using the System.runAs method. Inside the System.runAs block, the DML operation for the setup object (SetOwner__c) is performed, ensuring it runs in a separate user context. Outside this block, DML operations for non-setup objects, such as creating a Group, associating it with a QueueSObject, and inserting a Lead, are executed. This separation prevents the error by isolating setup and non-setup DML in distinct transactions within the test execution.

Solution 2: Using Asynchronous Processing in Non-Test Scenarios

For non-test scenarios, you can separate the DML operations into different transactions by using asynchronous processing techniques such as @future, Batch Apex, or Queueable Apex.
Here’s an example using @future:

public class MixedDmlHandler {
    @future
    public static void updateSetupObject(SetOwner__c mycs) {
        insert mycs; // Setup object DML in a separate transaction
    }

    public static void handleMixedDml() {
        // Non-setup object DML
        Group g1 = new Group(Name = 'group name', Type = 'Queue');
        insert g1;

        QueueSObject q1 = new QueueSObject(QueueID = g1.Id, SobjectType = 'Lead');
        insert q1;

        Lead lead = createNewLead(UserInfo.getUserId());
        insert lead;

        // Setup object DML
        SetOwner__c mycs = SetOwner__c.getValues('standardset');
        if (mycs == null) {
            mycs = new SetOwner__c(Name = 'CustomValues');
            mycs.OwnerId__c = '00520000000z3PrAAI';
            mycs.RecordtypeID__c = '012L00000004QsrIAE';
            updateSetupObject(mycs); // Call @future method
        }
    }
}

Code explanation:
The provided code resolves the MIXED_DML_OPERATION error in non-test scenarios by separating setup and non-setup DML operations into different transactions using an @future method. The handleMixedDml method performs non-setup object DML, such as creating a Group, associating it with a QueueSObject, and inserting a Lead. When dealing with the setup object (SetOwner__c), it uses the updateSetupObject method annotated with @future, ensuring the setup DML runs asynchronously in a separate transaction. This approach maintains transaction integrity while avoiding mixed DML errors.

Summing Up:

The MIXED_DML_OPERATION error occurs in Salesforce when attempting to perform DML operations on setup objects (like CustomSettings or User) and non-setup objects (like Lead or Account) within the same transaction. To address this, you can separate these operations into distinct transactions. In test scenarios, the System.runAs method allows setup object DML to run in a separate user context, isolating it from non-setup DML within the same test. For non-test scenarios, asynchronous techniques such as @future, Batch Apex, or Queueable Apex can be employed to defer setup DML operations to a separate transaction. By leveraging these approaches, developers can maintain transaction integrity while adhering to Salesforce’s restrictions, ensuring smooth operation of code across all scenarios.

Launch Your Salesforce Career with Expert Training in Delhi

Take your career to new heights with professional Salesforce training in Delhi from CRS Info Solutions. Designed to equip you with the skills needed to thrive in the fast-growing Salesforce ecosystem, our courses focus on practical learning with real-time project experience. From Salesforce Admin and Developer to cutting-edge AI modules, we cover it all with hands-on training led by industry experts.

Whether you’re a beginner exploring the Salesforce domain or an experienced professional looking to upgrade your skills, our training is tailored to meet your career goals. With personalized support, in-depth course materials, and expert guidance for certification and interview preparation, you’ll be fully prepared to excel in the industry.

Join us today for a free demo session and take the first step towards a rewarding Salesforce career!!!

Comments are closed.