1

I am trying to follow the best practice design patterns for triggers but get the error Constructor not defined: [CaseTriggerHandler].(). What am I missing?

Trigger

trigger CaseTrigger on Case (before insert, before update, before delete, after insert, after update, after delete, after undelete) {

    CaseTriggerHandler handler = new CaseTriggerHandler();

    //Before Insert
    if(Trigger.isInsert && Trigger.isBefore){
        handler.OnBeforeInsert(Trigger.new);
    }
    //After Insert
    else if(Trigger.isInsert && Trigger.isAfter){
        handler.OnAfterInsert(Trigger.new);
    }
    //Before Update
    else if(Trigger.isUpdate && Trigger.isBefore){
        handler.OnBeforeUpdate(Trigger.old, Trigger.new, Trigger.newMap);
    }
    //After Update
    else if(Trigger.isUpdate && Trigger.isAfter){
        handler.OnAfterUpdate(Trigger.old, Trigger.new, Trigger.newMap);
    }
    //Before Delete
    else if(Trigger.isDelete && Trigger.isBefore){
        handler.OnBeforeDelete(Trigger.old, Trigger.oldMap);
    }
    //After Delete
    else if(Trigger.isDelete && Trigger.isAfter){
        handler.OnAfterDelete(Trigger.old, Trigger.oldMap);
    }
    //After Undelete
    else if(Trigger.isUnDelete){
        handler.OnUndelete(Trigger.new);
    }
}

Handler

    public with sharing class CaseTriggerHandler {

    private boolean isExecuting = false;

    public CaseTriggerHandler(boolean isExecuting){
        this.isExecuting = isExecuting;
    }

    public void OnBeforeInsert(List<Case> newCases){
        //EXECUTE BEFORE INSERT LOGIC
    }

    public void OnAfterInsert(List<Case> newCases){
        //EXECUTE AFTER INSERT LOGIC
    }

    public void OnBeforeUpdate(List<Case> oldCases, List<Case> updatedCases, Map<Id, Case> CaseMap){
        //BEFORE UPDATE LOGIC
    }

    public void OnAfterUpdate(List<Case> oldCases, List<Case> updatedCases, Map<Id, Case> CaseMap){
        //AFTER UPDATE LOGIC
    }

    public void OnBeforeDelete(List<Case> CasesToDelete, Map<Id, Case> CaseMap){
        //BEFORE DELETE LOGIC
    }

    public void OnAfterDelete(List<Case> deletedCases, Map<Id, Case> CaseMap){
        //AFTER DELETE LOGIC
    }

    public void OnUndelete(List<Case> restoredCases){
        //AFTER UNDELETE LOGIC
    }

    public boolean IsTriggerContext{
        get{ return isExecuting;}
    }
}
1
  • You should never use Boolean parameters in your methods or constructors. It is a code smell.
    – Adrian Larson
    Jan 11, 2019 at 22:40

2 Answers 2

4

You are having this issue because you have a custom constructor written in your trigger handler CaseTriggerHandler as:

public CaseTriggerHandler(boolean isExecuting){
    this.isExecuting = isExecuting;
}

If you write a custom constructor and still want to be able to create a class by invoking no-argument constructor (CaseTriggerHandler handler = new CaseTriggerHandler(); as in your current code), then you will need to explicitly write a no- argument constructor.

If you create a constructor that takes arguments, and you still want to use a no-argument constructor, you must create your own no-argument constructor in your code. Once you create a constructor for a class, you no longer have access to the default, no-argument public constructor.

You can add a default no-arg constructor as:

public CaseTriggerHandler(){
    // do something
}
3
CaseTriggerHandler handler = new CaseTriggerHandler();

Your CaseTriggerHandler does not have a no-argument constructor:

public CaseTriggerHandler(boolean isExecuting){
    this.isExecuting = isExecuting;
}

You must either supply a Boolean, or implement a no-argument constructor that calls through to this one and provides a default value, e.g.,

public CaseTriggerHandler() {
    this(true);
}

You must log in to answer this question.

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