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 

Trigger works ok in web, small batches but fails upon API action

The trigger below deletes related objects when our custom object tracking sales coverage - Coverage_person__c - is deleted.

It works fine in the web site, works ok on dataloader deletes in small bacthes of 1, or 5, but at higher numbers it fails. 

Here is the code:

 

trigger CPChatterandATMDeleterBulked on Coverage_Person__c (before delete) 
{

    List<string> AcctIds = new List<string>();
    List<string> useIds = new List<string>();
    
    for(Coverage_Person__c p:trigger.old) 
    {
        AcctIds.add(p.Account__c);
        useIds.add(p.User__c);
    }
        
    List<EntitySubscription> esSet= [select id from EntitySubscription where ParentId IN :AcctIds and subscriberid IN :useIds];
    List <AccountTeamMember> atmList = [select id from AccountTeamMember where  UserId IN :useIds and AccountId IN :AcctIds];
    
    
     for(Coverage_Person__c p:trigger.old) 
    {
    
        
        
        delete esSet;
        delete atmList;      
    }
    
}

 here is the error when i try to delete a list of 16 records:

 

"CPChatterandATMDeleterBulked: execution of BeforeDelete

caused by: System.DmlException: Delete failed. First exception on row 0 with id 0E8K0000000JnNNKA0; first error: INVALID_CROSS_REFERENCE_KEY, invalid cross reference id: []

Trigger.CPChatterandATMDeleterBulked: line 22, column 1"

 

However if I shorten the list to 5 records, that record does not produce any error.

Any thoughts?

Thanks

Best Answer chosen by Admin (Salesforce Developers) 
SLockardSLockard

I'm not sure why it works with 5 and fails with 16, but I don't see why you are trying to delete the lists of related objects in a for loop.

I would think that both the lists (esSet, atmList) would get delted in the first iteration and wouldn't need to be deleted again.

Try deleting the bottom for loop and just having the two delete statements after they are declared.

All Answers

SLockardSLockard

I'm not sure why it works with 5 and fails with 16, but I don't see why you are trying to delete the lists of related objects in a for loop.

I would think that both the lists (esSet, atmList) would get delted in the first iteration and wouldn't need to be deleted again.

Try deleting the bottom for loop and just having the two delete statements after they are declared.

This was selected as the best answer
jaw999jaw999

thanks! I eliminated the second For loop and  just did a test with 67 and it  worked.

not sure why it was there - probably an artefact from consctrucing the trigger from another one. cheers.

SLockardSLockard

No problem, I'm glad I could help!

jaw999jaw999

Do you think you could help me with another trigger I am having the same issues with?

 

This is the trigger that creates the Account Team member and Chatter Subscription upon insertion of the new Coverage Person record. it works fine via web but now testing via API (data loader or Excel Connector) am getting various errors.

Not all inserted Coverage Persons will relate to a User record.

If I insert a lot of ones that don't find a record, it seems to work.

If I insert ONE Coverage Person for a person that has a User account it works. But if I insert a list with more than the 1 record that matches a user, I get errors.

Here is my code:

 

trigger CPChatterandATMAdder on Coverage_Person__c(After Insert) {
    List < EntitySubscription > esSet = new List < EntitySubscription > ();
    List < Double > empIds = new List < Double > ();
    List < AccountTeamMember > atms = new List < AccountTeamMember > ();
    List < string > CpAcctId = new List < String > ();
    List < string > CPUsers = new List < string > ();
    List < AccountShare > ASSES = new List < AccountShare > ();
    for (Coverage_Person__c p: trigger.new) {
        empIds.add(p.Emp_Id__c);
        CPusers.add(p.User__c);
        CpAcctId.add(p.Account__c);
    }
    List < User > userList = [select id, Emp_Id__c from User where isActive = True and EMP_ID__c IN: empIds];
    List < EntitySubscription > presubsList = [select SubscriberID from EntitySubscription where ParentId IN: CpAcctId];
    //Set < EntitySubscription > presubs = new set < EntitySubscription > ();
    //presubs.addAll(presubsList);
     Set<ID> presubs = new set<ID>();
      for(Entitysubscription es:presubsList){presubs.add(es.subscriberID);} 
      
    for (Coverage_Person__c p: trigger.new) {
        for (User a: userList) {
            if (! preSubs.contains(a.id))
            //if (preSubs.contains(a) == false)
            //         if( preSubsList.isempty())
            {
                EntitySubscription follow = new EntitySubscription(ParentId = p.Account__c, subscriberid = a.id);
                esSet.add(follow);
                AccountShare ASS = new AccountShare(AccountID = p.Account__c, UserOrGroupId = a.id, AccountAccessLevel = 'Edit', OpportunityAccessLevel = 'None');
                ASSES.add(ASS);
            }
            if (p.Emp_Id__c == a.Emp_Id__c) {
                AccountTeamMember atm = new AccountTeamMember(AccountId = p.Account__c, UserId = a.id, TeamMemberRole = p.Coverage_Role__c);
                atms.add(atm);
            }
        }
    }
    insert atms;
    insert ASSES;
    insert esSet;
}

 here is my error:

 

Insert Row Failed:
CPChatterandATMAdder: execution of AfterInsert

caused by: System.DmlException: Insert failed. First exception on row 2; first error: DUPLICATE_VALUE, duplicate value found: <unknown> duplicates value on record with id: <unknown>: []

Trigger.CPChatterandATMAdder: line 41, column 1

 

thanks!

jaw999jaw999

To break it down to what the problem lies - the subscriptions

trigger justSubscriptions on Coverage_Person__c (after insert) {

    List < EntitySubscription > esSet = new List < EntitySubscription > ();
    List < Double > empIds = new List < Double > ();
    List < string > CpAcctId = new List < String > ();
    List < string > CPUsers = new List < string > ();
   
    for (Coverage_Person__c p: trigger.new) {
        empIds.add(p.Emp_Id__c);
        CPusers.add(p.User__c);
        CpAcctId.add(p.Account__c);
    }
    List < User > userList = [select id, Emp_Id__c from User where isActive = True and EMP_ID__c IN: empIds];
    List < EntitySubscription > presubsList = [select SubscriberID from EntitySubscription where ParentId IN: CpAcctId];
    
     Set<ID> presubs = new set<ID>();
      for(Entitysubscription es:presubsList){presubs.add(es.subscriberID);} 
      
    for (Coverage_Person__c p: trigger.new) {
        for (User a: userList) {
            if (! preSubs.contains(a.id))
            {
                EntitySubscription follow = new EntitySubscription(ParentId = p.Account__c, subscriberid = a.id);
                esSet.add(follow);
            }
        }
    }
insert esSet;
}

 

SLockardSLockard

So the error comes from 2 or more subscriptions that have the same subscriberid ..

I'm a little confused on the code but try changing this:

     if (! preSubs.contains(a.id))

to this:

     if (preSubs.contains(a.id))

Again, I'm not sure if that will work, I'm just brainstorming ideas.

jaw999jaw999

the  

if (! preSubs.contains(a.id))

tells it if the person is not already a subscriber, then do the rest... so if i take that ! away it fires ok but it does nothing.

SLockardSLockard

Okay, so try changing it to this ..

      if (!preSubs.contains(a.id) && p.User__c == a.Id)

 

I think you're just missing a check dealing with how the coverage person relates to the user so something like that should be the solution.

jaw999jaw999

yes that seems to be working, thanks much!

SLockardSLockard

You're welcome.