I am trying to create a list of contacts and add these to the community as users. I keep getting the error:

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

I have walked trough some similar questions but could not apply these to my case. Could someone please explain.


public without sharing class addController {

    public static void saveContacts(List<Contact> listContact){
        Insert listContact;
        system.debug('listContact '+ listContact);

        User currentUser = [SELECT Id, Contact.AccountId FROM User WHERE Id =: UserInfo.getUserId() LIMIT 1];
        system.debug('currentUser '+ currentUser); 

        List<User> uList= new List<User>(); 
        List<Relatie__c> rel= new List<Relatie__c>(); 
        UserRole ur = [SELECT Id FROM UserRole Where name = 'Partner'];

        Profile profileId = [SELECT Id FROM Profile WHERE Name = 'Customer Community User' LIMIT 1];

        for(Contact con : listContact){

            Relatie__c rc = new Relatie__c(Account__c = currentUser.contact.AccountId, Contactpersoon__c = con.id ) ;
            system.debug('rc '+ rc);
            string alias = con.firstName.substring(0,1) + con.lastName.substring(0,1);
            user u = New user(userName = con.firstName+'.'+con.lastName+'@test.nl' ,
                              firstName = con.firstName, 
                              lastName = con.lastName, 
                              alias = alias, 
                              email = con.Email, 
                              communityNickName = alias, 
                              timeZoneSidKey = 'Europe/Amsterdam', 
                              LocaleSidKey = 'nl_NL', 
                              EmailEncodingKey = 'ISO-8859-1', 
                              LanguageLocaleKey = 'nl_NL', 
                              ContactID = con.id,
                              ProfileId = profileId.id,
                              UserRoleId = ur.id

            uList.add(u); }
        insert rel;
        system.debug('rel '+ rel);
        insert uList;


You need to move the User creation to a @future method. See also:

An example of how it might work would be something like:

public static void createUsers(Set<Id> contactIds)
    List<User> users = new List<User>();
    Profile profileToAssign = [SELECT Id FROM Profile WHERE ...];
    for (Contact record : [
        SELECT FirstName, LastName FROM Contact WHERE Id IN :contactIds
        users.add(new User(
            ContactId = record.Id,
            FirstName = record.FirstName,
            LastName = record.LastName,
            ProfileId = profileToAssign.Id
            // and so on
    insert users;

Then in your synchronous method, you remove all User logic and replace with:

Set<Id> contactIds = new Map<Id, Contact>(listContact).keySet();
| improve this answer | |
  • What if the user is created during SSO Registration? This currently doesn't throw any errors, but if you have setup objects created / modified as a result of a user being created (a process builder creating permission set assignments), a mixed dml error is thrown. I'm currently facing this issue and might open a case with support. – Glen De Marcos Sep 30 '19 at 20:19
  • Just to clarify, because provisioning is immediate during the registration process, @future cannot be used. – Glen De Marcos Sep 30 '19 at 20:20
  • @GlenDeMarcos That is an entirely separate question. It sounds interesting. Please post it as a question proper rather than asking in the comments, which is something you should avoid doing. You can link to this Q&A if you feel it helps provide context. – Adrian Larson Sep 30 '19 at 21:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.