0

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.

Apex

public without sharing class addController {
    @AuraEnabled

    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);
            rel.add(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;

    }
}

1 Answer 1

1

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

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

@future
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();
createUsers(contactIds);
3
  • 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. Sep 30, 2019 at 20:19
  • Just to clarify, because provisioning is immediate during the registration process, @future cannot be used. Sep 30, 2019 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, 2019 at 21:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .