function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
jaw999jaw999 

MIXED_DML_OPERATION - update User and AccountTeamMember - Need @future?

Help appreciated- am trying to add a User to Accounts via AccountTeamMembers as we track AccountTeams with custom relationship objects.

 

When a User gets activated (created or made active), my code finds where they have been linked with our custom objects and tries to insert an AccountTeamMember.

 

Gets me: one of those.... "System.DmlException: Insert failed. First exception on row 0; first error: MIXED_DML_OPERATION, DML operation on setup object is not permitted after you have updated a non-setup object (or vice versa): AccountTeamMember, original object: User: []: Trigger.UserActivatedTeamCoverage: line 59, column 1"

 

So it seems I have to do this asynchronusly - can someone assist in adding an @future notation to my code or directing me to guide on using the @future method?

thanks!

 

trigger UserActivatedTeamCoverage on User (after insert, after update) {

    //when a user is activated or inserted, the should be added to the AccountTeams of Accounts they cover via TeamMember
    
    
    // declare some lists
    
    List < EntitySubscription > esSet = new List < EntitySubscription > ();
    List < AccountTeamMember > atms = new List < AccountTeamMember > ();
    List <coverage_Person__c> CPS = new List <Coverage_Person__c> ();
    List < Double > empIds = new List < Double > ();
    List < ID > UserID = new List < ID > ();
    List < AccountShare > ASSES = new List < AccountShare > ();
    List <user> usersTriggering = new List <User> ();

   //add info from the users to the lists for users who are active and have an EMP_id (all should!)
   
    For (User u1:trigger.new){
        if(u1.isActive==true) if (u1.EMP_id__c !=null)
        empIds.add(u1.Emp_Id__c);
        UserID.add(u1.id);
        UsersTriggering.add(u1);
   }
   
   //get a list of team memberships for this person
   
   List <Coverage_Person__c> CP3 = [select name, id, emp_id__c, User__c, Coverage_Team__c  from Coverage_Person__c where emp_id__c IN: empIds];
   system.debug('CP3 the list of coverages=========================='+cp3);
   
   //add the teams to a list
    List <id> CP3Teams   = new List <ID>();
    for(Coverage_person__c es:cp3){CP3Teams.add(es.Coverage_Team__c);}
   system.debug('CP3Teams=======================the teams ids'+CP3Teams);
   
   
   //get the assigned teams of these Teams
   
   List <Assigned_Team__c> Assignments = [select name, id, emp_id__c, Account__c, Coverage_Team__c from Assigned_Team__c where Coverage_team__c IN: CP3Teams or EMP_id__c IN: empIds];
   system.debug('assignments========assigned teams========'+Assignments);
   
   //add the ids of the accounts from the AssTeams to a list
   List <id> AssignmentsAccounts = new List <id>();
   for (Assigned_Team__c os:Assignments){AssignmentsAccounts.add(os.Account__c);}
   system.debug('Assignments Accounts ids ======================= '+AssignmentsAccounts);
   
   //loop through User and find the link to the account, then create an accountTeamMember record for them
   
      For (User u1:UsersTriggering){
          For (Coverage_Person__c C:CP3){
              if(c.User__c==u1.id)
                  For (Assigned_Team__c at:Assignments){
                      if(at.Coverage_Team__c==c.Coverage_Team__c){
                      AccountTeamMember atm = new AccountTeamMember (AccountID=at.Account__c, UserId=u1.id, TeamMemberRole='Coverage');
                      atms.add(atm);
                   }
                }
                }
           }
    insert atms;
}

 

 

imutsavimutsav
you should create a new class and create a new method in that class
add @future keyword
Eg.
@future
public static void CreateUser(List<ID> UserID,Integer x,Map<ID,String> mapOfOldUserNames){

future method should be static I suppose. Now move all your logic to that future method. Now call this method from your trigger directly since this is a static method.
jaw999jaw999

Thanks, am checking it out.

Question, do i need to move the logic to the class or can I keep it in the trigger? Is there advantage to moving it?

jaw999jaw999

Thanks, helpful link.

Question:

I tried to start:

 

this change:

 

//truncated snippet:

For (User u1:UsersTriggering){
          For (Coverage_Person__c C:CP3){
              if(c.User__c==u1.id)
                  For (Assigned_Team__c at:Assignments){
                      if(at.Coverage_Team__c==c.Coverage_Team__c){
                      AccountTeamMember atm = new AccountTeamMember (AccountID=at.Account__c, UserId=u1.id, TeamMemberRole='Coverage');
                      atms.add(atm);
                   }
                }
                }
           }
   // insert atms;
   
   ActivatedUserInsertATM.InsertAtms(atms);
   
   

 

 

and this class:

 

public class ActivatedUserInsertATM {
 //@future
 
  public static void InsertAtms(List <AccountTeamMember> atms) {
    List<AccountTeamMember> NewAtms = new List<AccountTeamMember>();
 
     
 insert NewAtms;
 
 
 
 }
 }

 which compiled but did nothing.

If I uncomment @future, all kinds of compile issues come up.

Any help would be great, thanks.

jaw999jaw999
Ah, I see, cannot pass sObjects into @future. Will need to create collections for class