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;}
    }
}
  • You should never use Boolean parameters in your methods or constructors. It is a code smell. – Adrian Larson Jan 11 at 22:40
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);
}

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.