0

I am writing the trigger which maintains the sequence number in the insertion in various cases. So when I am trying to access this trigger for more than 500 records for multiple accounts it is throwing an error like :--

System.DmlException: Insert failed. First exception on row 600; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, ContactTrigger: execution of BeforeInsert caused by: System.DmlException: Update failed. First exception on row 0 with id 0035j00000JIEHbAAP;

public void beforeInsert(List<Contact> newConTrigger){      
conAcctsIdSet = new Set<Id>();
    for(Contact c : newConTrigger){
        System.debug('The c is ' + c);
        conAcctsIdSet.add(c.AccountId);
        
    }
    if(conAcctsIdSet.size()>0){
        conWithAcctsList = [Select Id,(Select Id,AccountId,Sequence_Number__c from Contacts Order By sequence_number__c ASC) from Account where Id IN:conAcctsIdSet];
        for(Account accts: conWithAcctsList){
            conListOld = new List<Contact>();
            con = new List<Contact>();
            conList = new List<Contact>();
            conMap = new Map<Integer,Contact>();
            conList.clear();
            for(Contact c : newConTrigger){
                if(c.AccountId == accts.id){
                    con.add(c);
                }
            }                
            if(accts.contacts.size()>0){
                for(Contact conRec : accts.contacts){
                    conMap.put((Integer)conRec.Sequence_Number__c,conRec);//fillig the with old values
                }
                System.debug('the old cons are ' + accts.contacts);
                conListOld.addAll(accts.contacts);
                System.debug('the conMap is 0'+conMap);
                addRecords(con,accts.id);
                for(Contact c : conMap.values()){
                    if(conListOld.contains(c)){
                        conList.add(c);
                    }
                }
            }
            else{
                System.debug('Elsepart');
                addRecords(con,accts.id);
            }
            
            if(conList.size()>0){
                update conList;
            }
        }
    } 
}
public void addRecords(List<Contact> newContacts,Id accId){
    for(Contact c : newContacts){
        Integer val = (Integer)c.Sequence_Number__c;
        System.debug('The new ARe :: ' + newContacts);
        if(accId == c.AccountId && conMap.containsKey(val)){
            for(Integer i = conMap.size()+1;i>val;i--){
                conMap.get(i-1).Sequence_Number__c = i; 
                conMap.put(i,conMap.get(i-1));
            }
            conMap.put((Integer)c.Sequence_Number__c,c);
            c.Sequence_Number__c = conMap.size()+1;
        }
        else{
            conMap.put((Integer)c.Sequence_Number__c , c);
        }
        System.debug('The Map is ::' + conMap);
    }          
} 
2
  • Is the handler a with or without sharing class? I'm wondering if there's a lack of sharing access to one of the referenced IDs...
    – Phil W
    Feb 6, 2022 at 20:13
  • It is with handler Feb 7, 2022 at 5:09

1 Answer 1

0

Your “update conList” statement will often include records from the “newConTrigger” variable, which will cause Salesforce to throw an error. The new records are added to the ‘con’ variable, which is delivered to the AddRecords method, which adds them to conMap. There is a loop that adds the conMap values to conList. Then conList is used for the update.

See this link: Updating Records in before trigger and Record Update in before trigger

If you just need to edit some values for the inbound records, you can set the attributes in your trigger, and they will be inserted with those values. It is very common for “before” triggers to set default values, and it works without using an DML statement.

7
  • NO! I have used conList only at one place and there I also used a check condition then how conList can contain elements of newConTrigger Feb 7, 2022 at 5:13
  • You use newConList to specifically match and add the contacts to "con" which are then passed to addRecords and get updated, so I think this answer is likely correct. Note, also, you use the nested loop anti-pattern to scan the accounts for matches in the contacts. You need to switch to using a map.
    – Phil W
    Feb 7, 2022 at 7:09
  • Can You please suggest how can I convert that thing to Map? Feb 7, 2022 at 12:18
  • To confirm that records from the trigger are included in the update statement, you can use sets (just for debugging purposes). Code like this will alert you: Set<contact toUpdate = new set<contact>(conList); Set<contact> fromTrigger = new set<contact>(newConTrigger); Boolean overlap = toUpdate.removeAll(fromTrigger); If (overlap) { System.debug(loggingLevel.warn, ‘OVERLAP FOUND’); }
    – SeanW
    Feb 7, 2022 at 14:52
  • No, Records are not overlapping I have checked by using this . Feb 7, 2022 at 17:59

You must log in to answer this question.

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