+ Start a Discussion
AxxxVAxxxV 

MIXED_DML_OPERATION Error

I am having the following error in my unit tests. I was unable to find any information on this error in the documentation. Would like to know if possible whether this is a current limitation in Apex, that is not documented, or I am missing something.

This woks fine in pre-summer 08 orgs, but is failing in my Summer 08 enabled sandboxes.

Here is my code

Code:
static testMethod void InsertInvestmentAccountBulkTriggerBypass(){


User user = [Select Id From User Where Id =: UserInfo.getUserId()];
user.Bypass_Triggers__c = 'SCS_Investment_Account_Time_Series__c;Asset';

update user;

System.assert(GlobalSettings.bypassTriggers('Asset'));
System.assert(GlobalSettings.bypassTriggers('SCS_Investment_Account_Time_Series__c'));

Test.startTest();
Map<Id, Asset> IAMap = unitTests.createTestAsset(200);
System.assertEquals(200, IAMap.size());
Test.stopTest();
}




public static Map<Id, Asset> createTestAsset(Integer numberOfRecords){

Map<Id, Asset> IAMap = new Map<Id, Asset>();
Asset [] IAs = new List<Asset>();

Account client = unitTests.createTestAccount();
Product2 fund = [Select Id from Product2 LIMIT 1]; //TODO: extract out as a helper method

for (Integer i=0; i<numberOfRecords; i++){
Asset IA = new Asset();

IA.Name = 'unitTest_IA';
IA.AccountId = client.Id;
IA.Product2Id = fund.Id;

IAs.add(IA);
}


public static Account createTestAccount(){

Account a = new Account();
a.Name = 'Test Account';
a.Employee_Id__c = '123456';
insert a;

System.assertEquals(1, [Select count() from Account where Id = : a.Id]);

return a;
}

insert IAs;

for(Asset ia : IAs){
IAMap.put(ia.Id, ia);
}

return
}

Full error message:

System.DmlException: Insert failed. First exception on row 0; first error: MIXED_DML_OPERATION, DML operation on non-setup object is not supported after you have updated a setup object: Account

Stack trace:
Class.unitTests.createTestAccount: line 94, column 9
Class.unitTests.createTestAsset: line 146, column 26
Class.TimeSeriesUnitTests.InsertInvestmentAccountBulkTriggerBypass: line 27, column 32



Basically, I need to update a current user record, prior to testing triggers. Problem is that I am not allowed to update a user record and then execute DML statements on other objects.


Message Edited by AxxxV on 05-28-2008 02:29 PM
Best Answer chosen by Admin (Salesforce Developers) 
jhartjhart
I'm running into the same problem.

It's possible to get the error inverted too (DML operation on setup object is not permitted after you have updated a non-setup object: User).

It seems that you can't mix updates to a User with updates to anything else.  Even in tests.  I don't know why.

This makes testing Users very difficult - in particular User triggers.  We cannot test User triggers that side-effect other objects (because updating the User will then end up updating the other object, and cause this error).

I'm going to have to comment out my effected tests & try to maintain code coverage in other ways.  Frustrating.

All Answers

jhartjhart
I'm running into the same problem.

It's possible to get the error inverted too (DML operation on setup object is not permitted after you have updated a non-setup object: User).

It seems that you can't mix updates to a User with updates to anything else.  Even in tests.  I don't know why.

This makes testing Users very difficult - in particular User triggers.  We cannot test User triggers that side-effect other objects (because updating the User will then end up updating the other object, and cause this error).

I'm going to have to comment out my effected tests & try to maintain code coverage in other ways.  Frustrating.
This was selected as the best answer
AxxxVAxxxV
This is a new behavior for the Summer '08 enabled orgs.

I hope someone from the product team comes accross this post and comments on it.

Is this an expected behavior going forward?
Should we start refactoring and commenting out our tests to accomodate this new limitation?

Or, will this be fixed by the time the release goes GA?
jhartjhart
This issue has now moved out of unit tests and is effecting production code, as of this morning.

See this post for more details.


AxxxVAxxxV
Actually, this error no longer occurs in our sandboxes. I just re-ran the unit tests in Production as well, and no issues there.

In our case, we only update user object within unit tests, so I know that this is fixed.
Since we do not update user object as part of our application logic outsude unit tests, I cannot tell whether that would cause an error or not....


Message Edited by AxxxV on 06-19-2008 03:21 PM
Scott.MScott.M
I just ran into this exception trying to upload a package. The weird thing is that it doesn't occur when I run the tests in the Eclipse IDE. It seems to be because I'm mixing setting up Custom Settings objects and just regluar old Custom Settings. This is definitely going to make testing hard as my code depends on the custom settings :(
Mat SchafferMat Schaffer

Looks like if you wrap your non-user manipulations in a System.runAs, you can get around this.

Sreejesh nairSreejesh nair

Thanks. This worked for me.