Skip to main content

We are using EDA and want to extend the TDTM functionality with an additional class on the Affiliation object. This class should evaluate if an Affiliation's primary checkbox field was previously TRUE and was changed to FALSE. If so, it should change the values of status and end date on the Affiliation. Our goal is that when the aligned Primary Affiliation field on the Contact is changed, the Affiliation record that is "unchecked" (formally the primary record but no longer) has an end date added and the status gets changed.

I created my class, added an entry to the Trigger Handler object, and have activated the class. However whenever I try to change the Primary Affiliation field on the Contact, I get the following error:: "System.SObjectException: DML statement cannot operate on trigger.new or trigger.old"

I have also pasted my code below, any help is appreciated. I'd like assurance that I have extended the TDTM functionality correctly, as the documentation is sparse and the error appears to be with how the class is trying to DML the record.

//

global class Aff_Extend_TDTM extends hed.TDTM_Runnable {

global override hed.TDTM_Runnable.DmlWrapper run(

List<Sobject> newlist,

List<SObject> oldlist,

hed.TDTM_Runnable.Action triggerAction,

Schema.DescribeSObjectResult objResult) {

hed.TDTM_Runnable.DmlWrapper dmlWrapper = new hed.TDTM_Runnable.DmlWrapper();

list<hed__Affiliation__c> loadAff = new list<hed__Affiliation__c>();

// Cast the trigger.new and trigger.old list into an Affiliation__c list

List<hed__Affiliation__c> triggernew = (list<hed__affiliation__c>)newlist;

List<hed__Affiliation__c> triggerold = (list<hed__affiliation__c>)oldlist;

// Make trigger.oldmap from triggr.old list

Map<Id, hed__Affiliation__c> triggeroldmap = new Map<Id, hed__Affiliation__c>();

for ( hed__Affiliation__c aff1 : triggerold )

triggeroldmap.put(

aff1.id

, aff1);

if (triggerAction == hed.TDTM_Runnable.Action.BeforeUpdate) {

// Compare values and determine if box was unchcked in this run

for (hed__Affiliation__c aff2 : triggernew ) {

hed__Affiliation__c oldAff = triggeroldmap.get(

aff2.Id

);

if(aff2.hed__Primary__c != oldAff.hed__Primary__c) {

System.debug('--* Aff Primary is changed*--');

aff2.hed__status__c = 'former';

aff2.hed__enddate__c = date.today();

loadAff.add(aff2);

}

}

dmlWrapper.objectsToUpdate.addAll((list<SObject>)loadAff);

}

return dmlWrapper;

}

}

3 answers
  1. Feb 11, 2020, 9:38 PM

    So you don't need to add the records to the list/add the list to the DML wrapper. You are updating the records in the trigger by reference, so you don't then need to also have a separate DML statement run on it. So if you just comment out the lines:

    loadAff.add(aff2);

    And then this one

    dmlWrapper.objectsToUpdate.addAll((list<SObject>)loadAff);

     

    you should fine it works as intended.

     

    You only need those DML wrappers if you are trying update other data e.g. related accounts you have queried for, new records you want to create.

0/9000