How to Overcome or fix MIXED_DML_OPERATION error in Salesforce APEX without future method ?

Posted by sathya on Geeks with Blogs See other posts from Geeks with Blogs or by sathya
Published on Fri, 25 May 2012 13:30:34 GMT Indexed on 2012/05/30 16:43 UTC
Read the original article Hit count: 240

Filed under:
How to Overcome or fix MIXED_DML_OPERATION error in Salesforce APEX without future method ?

MIXED_DML_OPERATION :-
one of the worst issues we have ever faced :)

While trying to perform DML operation on a setup object and non-setup object in a single action you will face this error.

Following are the solutions I tried and the final one worked out :-
1. perform the 1st objects DML on normal apex method. Then Call the 2nd objects DML through a future method.
    Drawback :- You cant get a response from the future method as its context is different and because its executing asynchronously and that its static.

2. Tried the following option but it didnt work :-
    1. perform the dml operation on the normal apex method.
    2. tried calling the 2nd dml from trigger thinking that it would be in a different context. But it didnt work.
    
3. Some suggestions were given in some blogs that we could try System.runas()
   Unfortunately that works only for test class.
   
4. Finally achieved it with response synchronously through the following solution :-
    a. Created 2 apex:commandbuttons :-
        1. <apex:commandButton value="Save and Send Activation Email" action="{!CreateContact}"  rerender="junkpanel" oncomplete="callSimulateUserSave()">
            Note :- Oncomplete will not work if you dont have a rerender attribute. So just try refreshing a junk panel.
        2. <apex:commandButton value="SimulateUserSave" id="SimulateUserSave" action="{!SaveUser}"  style="display:none;margin-left:5px;"/>
        Have a junk panel as well just for rerendering  :-
        <apex:outputPanel id="junkpanel"></apex:outputPanel>
    b. Created this javascript function which is called from first button's oncomplete and clicks the second button :-
                function callSimulateUserSave()
                {
                    // Specify the id of the button that needs to be clicked. This id is based on the Apex Component Hierarchy.
                    // You will not get this value if you dont have the id attribute in the button which needs to be clicked from javascript
                    // If you have any doubt in getting this value. Just hover over the button using Chrome developer tools to get the id.
                    // But it will show like theForm:SimulateUserSave but you need to replace the colon with a dot here.
                    // Note :- I have given display:none in the style of the second button to make sure that, it is not visible for the user.
                    var mybtn=document.getElementById('{!$Component.theForm.SimulateUserSave}');                
                    mybtn.click();
                }
    c. Apex Methods CreateContact and SaveUser are the pagereference methods which contains the code to create contact and user respectively.
       After inserting the user inside the second apex method you can just set some public Properties in the page,
       for ex:- created userid to get the user details and display in the page to show the acknowledgement to the users that the User is created.

© Geeks with Blogs or respective owner