Skip to main content
replaced http://salesforce.stackexchange.com/ with https://salesforce.stackexchange.com/
Source Link
  1. I changed the trigger to an After trigger. It's got a bunch more overhead (e.g. re-querying the records), but I was desperate and just trying anything different.

  2. In that After trigger, instead of doing the standard "Static Boolean"-based recursion prevention, I switched to "check the IDs you have already processed-based" recursion prevention as indicated herehere.

  1. I changed the trigger to an After trigger. It's got a bunch more overhead (e.g. re-querying the records), but I was desperate and just trying anything different.

  2. In that After trigger, instead of doing the standard "Static Boolean"-based recursion prevention, I switched to "check the IDs you have already processed-based" recursion prevention as indicated here.

  1. I changed the trigger to an After trigger. It's got a bunch more overhead (e.g. re-querying the records), but I was desperate and just trying anything different.

  2. In that After trigger, instead of doing the standard "Static Boolean"-based recursion prevention, I switched to "check the IDs you have already processed-based" recursion prevention as indicated here.

deleted 6 characters in body
Source Link
k..
  • 1.3k
  • 1
  • 13
  • 26

I have no idea what I actually did to make things workOkay, but they seem to be better now (just did a 150-record upsert that worked followed by a 170-record upsert that worked)...so the following helped:

Still not sure whyI'm glad it's working, but for future reference, does anyone have any suggestions how I could achieve the same "large dataset recursion prevention" effect with a simple "before"Before trigger refusedin this context? (There's no "Id" to play nice butlatch onto and cache at the "after" trigger works just fineclass level yet...)

I have no idea what I actually did to make things work, but they seem to be better now (just did a 150-record upsert that worked followed by a 170-record upsert that worked)...

Still not sure why a simple "before" trigger refused to play nice but the "after" trigger works just fine.

Okay, so the following helped:

I'm glad it's working, but for future reference, does anyone have any suggestions how I could achieve the same "large dataset recursion prevention" effect with a Before trigger in this context? (There's no "Id" to latch onto and cache at the class level yet...)

Post Undeleted by k..
Post Deleted by k..
Source Link
k..
  • 1.3k
  • 1
  • 13
  • 26

I have no idea what I actually did to make things work, but they seem to be better now (just did a 150-record upsert that worked followed by a 170-record upsert that worked)...

  1. I changed the trigger to an After trigger. It's got a bunch more overhead (e.g. re-querying the records), but I was desperate and just trying anything different.

  2. In that After trigger, instead of doing the standard "Static Boolean"-based recursion prevention, I switched to "check the IDs you have already processed-based" recursion prevention as indicated here.

New code:

public with sharing class ContactTriggerHandler {
...
    public static void copyDailyDumpDataAfterInsertOrUpdate(Map<Id,Contact> newContacts, Map<Id, Contact> oldContacts, Boolean isInsert) {
        // Make sure this method only runs once per set of just-inserted/updated contacts.
        if (alreadyProcessed.containsAll(newContacts.keySet())) {return;}
        alreadyProcessed.addAll(newContacts.keySet());
        
        List<Id> dumpCIds = new List<Id>();
        List<Contact> csToUpdate = new List<Contact>();
        
        for (Contact c : newContacts.values()) {
            // Cache as an "DDmp" Contact record if it was just inserted/updated by the DDmp Jitterbit load
            if (c.DailyDump_Contact_Id__c <> null &&
                c.DDmp_Jitterbit_Most_Recent_Load_DateTime__c <> null &&
                (isInsert ||
                 oldContacts == null ||
                 oldContacts.get(c.Id).DDmp_Jitterbit_Most_Recent_Load_DateTime__c == null ||
                 oldContacts.get(c.Id).DDmp_Jitterbit_Most_Recent_Load_DateTime__c < c.DDmp_Jitterbit_Most_Recent_Load_DateTime__c)
               ) {
                   dumpCIds.add(c.Id);
               }
        }
        
        if (dumpCIds.size()>0) {
            Boolean chgdDump = false;
            for (Contact c : [SELECT Id
                              ,PIDM__c,DDmp_Copy_of_PIDM__c
                              ,Banner_UST_ID__c,DDmp_Copy_Of_Banner_ID__c
                              ,Birthdate,DDmp_Birthdate__c
                              ,Citizenship__c,DDmp_Applicant_Citizenship_Status__c
                              ,Company_Holding_Spot__c,DDmp_Account_Name__c
                              ,Email,DDmp_Email__c
                              ,FirstName,DDmp_FirstName__c
                              ,Gender__c,DDmp_Gender__c
                              ,MailingStreet,DDmp_MailingStreetLine1__c,DDmp_MailingStreetLine2__c,DDmp_MailingStreetLine3__c
                              ,MailingCity,DDmp_MailingCity__c
                              ,MailingState,DDmp_MailingState__c
                              ,MailingPostalCode,DDmp_MailingZip__c
                              ,MailingCountry,DDmp_MailingCountry__c
                              ,Phone,OtherPhone,DDmp_HomePhone__c,DDmp_MobilePhone__c,DDmp_Work_Phone__c
                              FROM Contact WHERE Id IN :dumpCIds]) {
                                  {
                                      // Smart-edit various fields
                                      if (c.PIDM__c==null && c.DDmp_Copy_of_PIDM__c<>null) c.PIDM__c = c.DDmp_Copy_of_PIDM__c; chgdDump=TRUE;
                                      if (c.Banner_UST_ID__c==null && c.DDmp_Copy_Of_Banner_ID__c<>null) c.Banner_UST_ID__c = c.DDmp_Copy_Of_Banner_ID__c; chgdDump=TRUE;
                                      if (c.Birthdate==null && c.DDmp_Birthdate__c<>null) c.Birthdate = c.DDmp_Birthdate__c; chgdDump=TRUE;
                                      if (c.Citizenship__c==null && c.DDmp_Applicant_Citizenship_Status__c<>null) c.Citizenship__c = c.DDmp_Applicant_Citizenship_Status__c; chgdDump=TRUE;
                                      if (c.Company_Holding_Spot__c==null && c.DDmp_Account_Name__c<>null) c.Company_Holding_Spot__c = c.DDmp_Account_Name__c; chgdDump=TRUE;
                                      if (c.Email==null && c.DDmp_Email__c<>null) c.Email = c.DDmp_Email__c; chgdDump=TRUE;
                                      System.debug('First names:  ' + c.FirstName + c.DDmp_FirstName__c); // DEBUG LINE ONLY
                                      if ((c.FirstName==null || Test.IsRunningTest()) && c.DDmp_FirstName__c<>null) c.FirstName = c.DDmp_FirstName__c; chgdDump=TRUE; // To make debug logs easier to read, our test to make sure this works starts with a FirstName in place, unlike real data, hence the alternative check for isRunningTest for overwriting.
                                      if (c.Gender__c==null && c.DDmp_Gender__c<>null) c.Gender__c = c.DDmp_Gender__c; chgdDump=TRUE;
                                      if (c.MailingStreet==null && c.DDmp_MailingStreetLine1__c<>null) c.MailingStreet = c.DDmp_MailingStreetLine1__c +
                                          ((c.DDmp_MailingStreetLine2__c <> null) ? ('\r\n' + c.DDmp_MailingStreetLine2__c) : '') +
                                          ((c.DDmp_MailingStreetLine3__c <> null) ? ('\r\n' + c.DDmp_MailingStreetLine3__c) : ''); chgdDump=TRUE;
                                      if (c.MailingCity==null && c.DDmp_MailingCity__c<>null) c.MailingCity = c.DDmp_MailingCity__c; chgdDump=TRUE;
                                      if (c.MailingState==null && c.DDmp_MailingState__c<>null) c.MailingState = c.DDmp_MailingState__c; chgdDump=TRUE;
                                      if (c.MailingPostalCode==null && c.DDmp_MailingZip__c<>null) c.MailingPostalCode = c.DDmp_MailingZip__c; chgdDump=TRUE;
                                      if (c.MailingCountry==null && c.DDmp_MailingCountry__c<>null) c.MailingCountry = c.DDmp_MailingCountry__c; chgdDump=TRUE;
                                      // Take phone number from best in preference order Home, Mobile, Work
                                      if (c.Phone==null) {
                                          if (c.DDmp_HomePhone__c<>null) {c.Phone=c.DDmp_HomePhone__c; chgdDump=TRUE;}
                                          else if (c.DDmp_MobilePhone__c<>null) {c.Phone=c.DDmp_MobilePhone__c; chgdDump=TRUE;}
                                          else c.Phone=c.DDmp_Work_Phone__c; chgdDump=TRUE;
                                      }
                                      // If another phone exists, take it from 2nd-best in preference order Home, Mobile, Work
                                      if (c.OtherPhone == null) {
                                          if (c.DDmp_HomePhone__c<>null) {c.OtherPhone = (c.DDmp_MobilePhone__c<>null) ? c.DDmp_MobilePhone__c : c.DDmp_Work_Phone__c ; chgdDump=TRUE;}
                                      }
                                  }
                                  // If anything was smart-edited, set the record aside for updating
                                  if (chgdDump) csToUpdate.add(c);
                                  chgdDump=FALSE;
                              }
        }
        
        if(csToUpdate.size()>0) {
            UPDATE csToUpdate;
        } 
    }
    ...
}

Still not sure why a simple "before" trigger refused to play nice but the "after" trigger works just fine.