mitchspano/apex-trigger-actions-framework

Finalizer Method is not working as expected

Closed this issue · 2 comments

Expected Behavior : The List of Opportunity to be updated is sent to Finalizer class and expecting DML update. Note: Metadata record is created.

Actual Behavior : No action is performed. Finalizer execute method is not getting called. As mentioned , the FinalizerHandler.Context is empty.

Steps to Reproduce the Problem

  1. Created the same helper class related to Opportunity as mentioned in the article
  2. Created Metadata record under Finalizer
  3. On Updating the opportunity, No update DML executed.

Kindly let me know whether i am missing anything to call the Finalizer execute method.

The system is working as intended.

trigger OpportunityTrigger on Opportunity (
  before insert,
  after insert,
  before update,
  after update,
  before delete,
  after delete,
  after undelete
) {
  new MetadataTriggerHandler().run();
}
public with sharing class Finalizer implements TriggerAction.DmlFinalizer {
  public void execute(FinalizerHandler.Context context) {
    System.debug('Finalized!');
  }
}

image

Execute anonymous:

insert new Opportunity(
    Name = 'Demo',
    StageName = 'Prospecting',
    CloseDate = Date.today()
);

Here is the log for the transaction:

59.0 APEX_CODE,DEBUG;APEX_PROFILING,INFO;CALLOUT,INFO;DB,INFO;NBA,INFO;SYSTEM,DEBUG;VALIDATION,INFO;VISUALFORCE,INFO;WAVE,INFO;WORKFLOW,INFO
Execute Anonymous: insert new Opportunity(
Execute Anonymous:     Name = 'Demo',
Execute Anonymous:     StageName = 'Prospecting',
Execute Anonymous:     CloseDate = Date.today()
Execute Anonymous: );
08:21:19.5 (5301560)|USER_INFO|[EXTERNAL]|0058G000006FbRq|test-gx0tgjho8l0n@example.com|(GMT-08:00) Pacific Standard Time (America/Los_Angeles)|GMT-08:00
08:21:19.5 (5331017)|EXECUTION_STARTED
08:21:19.5 (5341046)|CODE_UNIT_STARTED|[EXTERNAL]|execute_anonymous_apex
08:21:19.5 (6237065)|DML_BEGIN|[1]|Op:Insert|Type:Opportunity|Rows:1
08:21:19.5 (44688309)|CODE_UNIT_STARTED|[EXTERNAL]|01q8G000000sheL|OpportunityTrigger on Opportunity trigger event BeforeInsert|__sfdc_trigger/OpportunityTrigger
08:21:19.5 (56921130)|SYSTEM_MODE_ENTER|false
08:21:19.5 (57027858)|SYSTEM_MODE_EXIT|false
08:21:19.5 (57155855)|SYSTEM_MODE_ENTER|false
08:21:19.5 (57181471)|SYSTEM_MODE_EXIT|false
08:21:19.5 (57192255)|SYSTEM_MODE_ENTER|false
08:21:19.5 (57200220)|SYSTEM_MODE_EXIT|false
08:21:19.5 (65364548)|SOQL_EXECUTE_BEGIN|[433]|Aggregations:0|SELECT Apex_Class_Name__c, Order__c, Flow_Name__c, Bypass_Permission__c, Required_Permission__c, Allow_Flow_Recursion__c, BEFORE_INSERT__r.Bypass_Permission__c, BEFORE_INSERT__r.Required_Permission__c FROM Trigger_Action__mdt WHERE BEFORE_INSERT__c != NULL AND BEFORE_INSERT__r.Object_API_Name__c = 'Opportunity' AND BEFORE_INSERT__r.Object_Namespace__c = '' AND BEFORE_INSERT__r.Bypass_Execution__c = FALSE AND Bypass_Execution__c = FALSE ORDER BY Order__c ASC
08:21:19.5 (82321277)|SOQL_EXECUTE_END|[433]|Rows:0
08:21:19.83 (83016933)|CUMULATIVE_LIMIT_USAGE
08:21:19.83 (83016933)|LIMIT_USAGE_FOR_NS|(default)|
  Number of SOQL queries: 0 out of 100
  Number of query rows: 0 out of 50000
  Number of SOSL queries: 0 out of 20
  Number of DML statements: 1 out of 150
  Number of Publish Immediate DML: 0 out of 150
  Number of DML rows: 1 out of 10000
  Maximum CPU time: 0 out of 10000
  Maximum heap size: 0 out of 6000000
  Number of callouts: 0 out of 100
  Number of Email Invocations: 0 out of 10
  Number of future calls: 0 out of 50
  Number of queueable jobs added to the queue: 0 out of 50
  Number of Mobile Apex push calls: 0 out of 10

08:21:19.83 (83016933)|CUMULATIVE_LIMIT_USAGE_END

08:21:19.5 (83331474)|CODE_UNIT_FINISHED|OpportunityTrigger on Opportunity trigger event BeforeInsert|__sfdc_trigger/OpportunityTrigger
08:21:19.5 (135492231)|CODE_UNIT_STARTED|[EXTERNAL]|01q8G000000sheL|OpportunityTrigger on Opportunity trigger event AfterInsert|__sfdc_trigger/OpportunityTrigger
08:21:19.5 (137486570)|SOQL_EXECUTE_BEGIN|[433]|Aggregations:0|SELECT Apex_Class_Name__c, Order__c, Flow_Name__c, Bypass_Permission__c, Required_Permission__c, Allow_Flow_Recursion__c, AFTER_INSERT__r.Bypass_Permission__c, AFTER_INSERT__r.Required_Permission__c FROM Trigger_Action__mdt WHERE AFTER_INSERT__c != NULL AND AFTER_INSERT__r.Object_API_Name__c = 'Opportunity' AND AFTER_INSERT__r.Object_Namespace__c = '' AND AFTER_INSERT__r.Bypass_Execution__c = FALSE AND Bypass_Execution__c = FALSE ORDER BY Order__c ASC
08:21:19.5 (148481819)|SOQL_EXECUTE_END|[433]|Rows:0
08:21:19.5 (149908852)|SYSTEM_MODE_ENTER|false

 // FINALIZER IS EXECUTED HERE
08:21:19.5 (155720269)|USER_DEBUG|[3]|DEBUG|Finalized!


08:21:19.5 (155793952)|SYSTEM_MODE_EXIT|false
08:21:19.155 (155836482)|CUMULATIVE_LIMIT_USAGE
08:21:19.155 (155836482)|LIMIT_USAGE_FOR_NS|(default)|
  Number of SOQL queries: 0 out of 100
  Number of query rows: 0 out of 50000
  Number of SOSL queries: 0 out of 20
  Number of DML statements: 1 out of 150
  Number of Publish Immediate DML: 0 out of 150
  Number of DML rows: 1 out of 10000
  Maximum CPU time: 0 out of 10000
  Maximum heap size: 0 out of 6000000
  Number of callouts: 0 out of 100
  Number of Email Invocations: 0 out of 10
  Number of future calls: 0 out of 50
  Number of queueable jobs added to the queue: 0 out of 50
  Number of Mobile Apex push calls: 0 out of 10

08:21:19.155 (155836482)|CUMULATIVE_LIMIT_USAGE_END

08:21:19.5 (156165976)|CODE_UNIT_FINISHED|OpportunityTrigger on Opportunity trigger event AfterInsert|__sfdc_trigger/OpportunityTrigger
08:21:19.5 (161370428)|DML_END|[1]
08:21:19.190 (190604510)|CUMULATIVE_LIMIT_USAGE
08:21:19.190 (190604510)|LIMIT_USAGE_FOR_NS|(default)|
  Number of SOQL queries: 0 out of 100
  Number of query rows: 0 out of 50000
  Number of SOSL queries: 0 out of 20
  Number of DML statements: 1 out of 150
  Number of Publish Immediate DML: 0 out of 150
  Number of DML rows: 1 out of 10000
  Maximum CPU time: 0 out of 10000
  Maximum heap size: 0 out of 6000000
  Number of callouts: 0 out of 100
  Number of Email Invocations: 0 out of 10
  Number of future calls: 0 out of 50
  Number of queueable jobs added to the queue: 0 out of 50
  Number of Mobile Apex push calls: 0 out of 10

08:21:19.190 (190604510)|CUMULATIVE_LIMIT_USAGE_END

08:21:19.5 (190719818)|CODE_UNIT_FINISHED|execute_anonymous_apex
08:21:19.5 (190741095)|EXECUTION_FINISHED

Dear Mitchspano,

I am currently assuming that, through Finalizers we can do single DML for the entire transaction per object. Kindly confirm whether my understanding is correct.

Kindly check my code below and let me know your suggestions.

ApexTrigger:
trigger CEP_OpportunityTrigger on Opportunity (
before insert,
after insert,
before update,
after update,
before delete,
after delete,
after undelete
) {
new MetadataTriggerHandler().run();
}

Apex Class:

public class CEP_TA_Opportunity_RecalculateCategory implements TriggerAction.AfterUpdate {

public void afterUpdate(List newList, List oldList) {
Map<Id,Opportunity> oldMap = new Map<Id,Opportunity>(oldList);
List oppsToBeUpdated = new List();
for (Opportunity opp : newList) {
if (
TriggerBase.idToNumberOfTimesSeenAfterUpdate.get(opp.id) == 1 &&
opp.StageName != oldMap.get(opp.id).StageName
) {
Opportunity curOpp = new Opportunity (Id = opp.id);
curOpp.Type = 'Existing Business';
oppsToBeUpdated.add(curOpp);
}
}
if (!oppsToBeUpdated.isEmpty()) {
this.recalculateCategory(oppsToBeUpdated);
}
}
private void recalculateCategory(List opportunities) {
CEP_OpportunityCategoryCalculator.registerOpportunities(opportunities);
}

}

Apex class: CEP_OpportunityCategoryCalculator
public with sharing class CEP_OpportunityCategoryCalculator implements Queueable, TriggerAction.DmlFinalizer {

private static List toProcess = new List();
private List currentlyProcessing;

public static void registerOpportunities(List toRecalculate) {
system.debug('## Inside CEP_OpportunityCategoryCalculator Class ##');
toProcess.addAll(toRecalculate);
}

public void execute(FinalizerHandler.Context context) {
system.debug('## Inside Execute CEP_OpportunityCategoryCalculator Class ##' + toProcess);
if (!toProcess.isEmpty()) {
this.currentlyProcessing = toProcess;
System.enqueueJob(this);
toProcess.clear();
system.debug('## End of Execute CEP_OpportunityCategoryCalculator Class ##');

}

}

public void execute(System.QueueableContext qc) {
// do some stuff
}
}

Am also having Finalizer class
public with sharing class Finalizer implements TriggerAction.DmlFinalizer {
public void execute(FinalizerHandler.Context context) {
System.debug('Finalized!');
}
}

I tried the following CMDT record
Finalizer

I have also tried by changing the Apex class from Finalizer to CEP_OpportunityCategoryCalculator, but DML is not happening.

Kindly let me know whether Finalizer will take care of DMLs or do we need to write DML statements separately in helper class.

Also, please do share some sample codes/videos related to DML finalizers.

Thank you for your help

Thanks,
Sethu.