0

Background Scenario : I have to insert records in a object through X-author file. This file may contain duplicates and I have to avoid duplicate insertion. Duplicates are considered on the basis of two fields (Apttus_Proposal__Proposal__c AND APTS__Part_Number__c). I have written the trigger code to get the duplicate Ids and the I am deleting them at the end of the insertion of all the records.

The code is working fine even if I insert more than 1000+ records through data loader. But it is throwing the 'Apex CPU Time Limit Exceeded' error if we are using the Apptus X-Author for excel.

I believe that on bulkifying the trigger it may not throw the error. I do not have much knowledge on how to use MAPS . So request you to please help me with this. Below is that part of trigger which needs to be bulkified. I am not adding full code since it is very huge.

FOR(Apttus_Proposal__Proposal_Line_Item__c PLI1 : ListPLIs)
        {
            PropProdId = PLI1.Apttus_Proposal__Proposal__c + PLI1.APTS_Part_Number__c;
            System.Debug('---PropProdId---'+PropProdId);
            IdCount = 0;
            PLIIds = '';

            FOR(Apttus_Proposal__Proposal_Line_Item__c PLI2 : ListPLIs)
            {
                IF((PLI2.Apttus_Proposal__Proposal__c + PLI2.APTS_Part_Number__c) == PropProdId)
                {
                    IdCount = IdCount + 1;
                    PLIIds = PLI2.Id + ';';
                }
            }
            System.Debug('---IdCount---'+IdCount);  System.Debug('---PLIIds---'+PLIIds);        

            IF(IdCount > 1)
            {
                FOR(String Str : PLIIds.Split(';'))
                {
                    DPLIList.Add(Str);     //These are the duplicate IDs               
                }
            }
            IF(IdCount == 1)
            {
                FOR(String Str : PLIIds.Split(';'))
                {
                    UPLIList.Add(Str);        //These are the unique Ids            
                }
            }
      }

In the above code I am running the FOR loop 2 times over the same list of records which needs to be inserted from excel. And then I am trying to check that if I get the field combinations more than one time then I am adding it in the duplicate list.

  • If this is invoked by a trigger, it will be impossible to delete duplicates in the before insert scope. You can mark them as in error though so they don't save. – cropredy Aug 8 '16 at 15:30
  • @cropredy : I am deleting the records after insert. So is it possible somehow to bulkify code in that way ? – Ruchi Aug 8 '16 at 16:48
  • how are you deleting after insert? what tells you which records to delete? Information is missing from OP – cropredy Aug 8 '16 at 17:36
  • @cropredy: The DPLIist(Duplicate list) tells me which ones to delete. – Ruchi Aug 9 '16 at 10:05
1

I'm not sure if your provided code alone is responsible for pushing you over the CPU limit. It can definitely be improved, but there just doesn't seem to be enough code in your nested loop to cause an issue with a modest number of records.

You mention wanting to try to use a Map here, but I think you only need to use a Set. You're only interested in determining if you've encountered PLI2.Apttus_Proposal__Proposal__c + PLI2.APTS_Part_Number__c before. Once you have that information, you simply add the Id to the appropriate list (unique/duplicate).

The Set class has a method which will do a lot of the work for you called .contains(). This method returns true if the argument you pass currently exists in the set, and false otherwise. This will allow us to eliminate your inner loop.

Set<String> proposalKeys = new Set<String>();
for(Apttus_Proposal__Proposal_Line_Item__c PLI1 : ListPLIs){
    PropProdId = PLI1.Apttus_Proposal__Proposal__c + PLI1.APTS_Part_Number__c;

    if(proposalKeys.contains(PropProdId)){
        // In this If block, we know that we've already seen the proposal id.
        // Add this record's id to the duplicate collection
        DPLIList.add(PLI1.Id);
    } else {
        // In this else block, we know that this is the first time we've seen 
        //  the proposal id.
        //  Add the record id to the unique collection, and put the 
        //    proposal id in the set so we can detect any duplicates.
        UPLIList.add(PLI1.Id);
        proposalKeys.add(PropProdId)
    }
}
| improve this answer | |
  • No id's are getting added in the DPList. In the debug log the size of list shows as 0 at the end even if i insert duplicate records. – Ruchi Aug 9 '16 at 12:13
  • @Ruchi If there is an issue with my code, and DPLIList.size() == 0, then proposalKeys.size() should be different (strictly less) than UPLIList.size(). Can you run your test again and debug the size of all 3 collections? If those two collections are the same size, then the issue must be located in some of the trigger logic that you didn't provide. The first thing that comes to my mind is that you may be inserting the duplicate record in a separate transaction, and your trigger may only work on the records in Trigger.new. – Derek F Aug 9 '16 at 14:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.