Tuesday, January 12, 2016

MIXED_DML_OPERATION Error in Salesforce



If you are a hands on Salesforce developer, more often than sometimes you would run into  

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

What this error is (Skip this section if you already know what this is)


DML operations on certain sObjects can’t be mixed with other sObjects in the same transaction. This is because some sObjects affect the user’s access to records in the organization. These types of sObjects must be inserted or updated in a different transaction to prevent operations from happening with incorrect access level permissions. For example, you can’t update an account and a user role in a single transaction. However, there are no restrictions on delete DML operations.

More about this here 

Something like this will typically result in the MIXED_DML_OPERATION




Getting Around this error( Future Method)
1. Create one method to perform the DML on one of the SObject(Say Contact)
2. Create another method to perform the DML on another SObject (Say User) - Make this second method a future call.

In my case I needed to convert the insertion of User_History__c records into a future call
I thought of something like this –



and then calling this from within my LogHistory method.

One small problem with this approach was that future methods only accept primitive data types as parameters, meaning you can only pass Id, string, Integers and their collections.
So I would need to pass Ids and query the records again in future method, and very likely I would have required to rewrite the entire logic to make it work with future method.
I did not want to do this.

Entry of the hero of this blog post - Serialization.

so what i ended up doing is –





In essence, JSON.serialize will give you the string representation of your object or wrapper class or pretty much anything and using JSON.deserialize you can reconstruct your object back - thus overcoming the Primitive data types parameters only restriction of @future methods. 

Cheers!!