0

I have a trigger that creates an AccountTeamMember object every time there is an update to an Account_Ownership__c object (this is a custom object that we've created in house to act more in line with what we needed).

(More Specifically, every time there is an update to an Account_Ownership__c object, my code deletes all AccountTeamMembers(and AccountShares), gets a list of all Account_Ownership__Cs on the related Account, and creates a new AccountTeamMember for each one)

As far as we can tell, when we use data loader to update 50,000 records in batches of 200, only one record per batch is being updated. I think my code should be able to handle bulk updates, so I was looking for some insight as to what may be causing these results. code below

Trigger:

trigger AccountOwnershipTrigger on Account_Ownership__c (before insert, before update, after insert, after update, after delete) {
...
...

if(Trigger.isAfter){
     if(Trigger.isUpdate){
        AccountOwnershipTriggerHelper.updateAccountTeamUsers(Trigger.new, Trigger.oldMap);
}

Code:

 public static void updateAccountTeamUsers(List<Account_Ownership__c> newAcctOwnership, Map<Id, Account_Ownership__c> oldAcctOwnership){        

    // Gets a list of current Account Team Members
    List<AccountTeamMember> acctTeamMembers = getAccountTeams(oldAcctOwnership);

    List<AccountTeamMember> currentTeamMembers = new List<AccountTeamMember>();
    List<AccountShare> currentAccountShares = new List<AccountShare>();
    String acctID = '';

    String backupAcctID = '';

    // If there is at least one current Account Team Member
    if (acctTeamMembers.size() > 0){

        // Gets the AccountId of the first Team Member
        acctID = acctTeamMembers[0].AccountID;

        // Gets a list of all current Account Team Members
        currentTeamMembers = [select id, userid from AccountTeamMember where accountID =:acctTeamMembers[0].AccountId];

        currentAccountShares = [select id from AccountShare where accountID =: acctId AND RowCause = 'Manual'];

    // If there is at least one current Team Member,
    // Delete all Account Team Members
    if(currentTeamMembers.size() > 0){
        for(AccountTeamMember atm: currentTeamMembers){
            AccountTeamMember tempTeamMember = new AccountTeamMember();
            tempTeamMember = atm;
            delete tempTeamMember;
        }
    }
        if(currentAccountShares.size()>0){
            for(AccountShare acctShare: currentAccountShares){
                AccountShare tempShare = new AccountShare();
                tempShare = acctShare;
                delete tempshare;
            }
        }

    List<Account_Ownership__c> uniqueAccountOwnerships = new List<Account_Ownership__c>();
    uniqueAccountOwnerships = [select id, user__c, account__c from Account_Ownership__c where Salesforce_Account_ID__C =:acctId];
    addUserToAccountTeam(uniqueAccountOwnerships);

    }
    // If there are no Team Members, but there is at least one new Account Ownership Being added
    else if(newAcctOwnership.size() > 0)
    {
        try{
            // Gets the AccountId of the first new Account Ownership
            backupAcctID = newAcctOwnership[0].Account__c; 

            List<Account_Ownership__c> backupUniqueAccountOwnerships = new List<Account_Ownership__c>();

            // Selects all Account Ownerships from the current Account
            backupUniqueAccountOwnerships = [select id, user__c, account__c from Account_Ownership__c where Salesforce_Account_ID__C =:backupAcctId];

            // Adds all Account Ownerships to Account Team Members
            addUserToAccountTeam(backupUniqueAccountOwnerships);
        }
        catch (Exception e){
            System.debug('You cant DO that');
        }

    }

Also: I know this is a wildy ineffiecient way to do what I wan't to do, but we were super hard pressed for time and needed to get a solution out ASAP (Please don't judge)

3
  • @ErricSSH, thanks for the feedback mate, any other thoughts? Commented Apr 19, 2019 at 16:28
  • For starters can you update your question with what your trying to do? I think we can infer what you want to do but why you only want the 1 account isn't entirely clear(I deleted my old comment because it wasn't helping)
    – EricSSH
    Commented Apr 19, 2019 at 16:29
  • @EricSSH Thanks man, I appreciate the help, I think I've figured it out Commented Apr 19, 2019 at 17:26

1 Answer 1

3

This code is written throughout to process exactly one record. That's what all your references to [0] are doing - you take the first elements in the list and never iterate over the inbound Account Ownership records or their related Accounts.

acctID = acctTeamMembers[0].AccountID;
// Gets a list of all current Account Team Members
currentTeamMembers = [select id, userid from AccountTeamMember where accountID =:acctTeamMembers[0].AccountId];

currentAccountShares = [select id from AccountShare where accountID =: acctId AND RowCause = 'Manual'];

and

backupAcctID = newAcctOwnership[0].Account__c; 
backupUniqueAccountOwnerships = [select id, user__c, account__c from Account_Ownership__c where Salesforce_Account_ID__C =:backupAcctId];

If you did iterate over your inputs, your code would immediately fail on your bulk uploads because you are, or would be, performing SOQL and DML in loops, on single-record contexts. The SOQL limit is 100 queries per transaction. The DML limit is 150 operations per transaction.

I think you may be overcomplicating your logic, and the easy way to address this requirement is a "wipe and refresh" strategy on all of the Accounts whose Ownership records are touched. That could look something like this:

  1. Iterate over your incoming Account Ownership records and accumulate the Ids of their related Accounts in a Set.
  2. Perform two queries - one for AccountTeamMember and one for AccountShare, both filtering by your Set of Account Ids. You delete all of the results, using two delete DML operations (one per list).
  3. You perform exactly one query against Account Ownership, filtering by your Set of Account Ids, to get the current complete set of Ownership records for all those Accounts which experienced any change.
  4. You iterate over those records and build up a List<AccountTeamMember> and List<AccountShare> in memory as you process those Ownership records (for all of the implicated Accounts).
  5. Lastly, you perform exactly two DML operations: one to insert the List<AccountTeamMember> and one to insert the List<AccountShare>.
0

You must log in to answer this question.

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