BeforeDelete
Runs in before delete, before records are removed. The rows are still in the database and still linked. Block a delete here, or clean up the records that point at it.
Roles
- Handler: the only role here. Block a delete with
addError, or clean up related records.
Add-ons
- PriorParentQuery: load the parent the old row pointed to; read it with
getOldParent. - RelatedQuery: query children, siblings or any other records once per chunk; read them with
getRelated. - Bypassable: skip this handler for the whole chunk when a condition holds.
- Finalizer: run once after this handler’s records, with the records that qualified.
- ContinueOnError: log and swallow this handler’s exceptions, so the save goes on.
Register
Implement TriggerOrchestrator.BeforeDelete on the orchestrator and return the handlers from beforeDeleteHandlers(). List order is run order. The trigger must list before delete and call TriggerOrchestrator.run(new ContactTriggerOrchestrator()).
apex
public with sharing class ContactTriggerOrchestrator implements TriggerOrchestrator.BeforeDelete {
public List<BeforeDelete.Handler> beforeDeleteHandlers() {
return new List<BeforeDelete.Handler>{ new ContactHandler() };
}
}Good to Know
- Ids are set.
record.getId()andrecords.getIds()return the Ids of the records being deleted. Their children can still be queried. - DML is allowed. There is no DML guard and no unit of work. A statement runs at once and fires the triggers of the records it writes. Collect in
onBeforeDeleteand write once in a Finalizer. - Leave the records being deleted alone. DML on a
Trigger.oldrow throws. Deleting a fresh instance of one fails withSELF_REFERENCE_FROM_TRIGGER. - Cascade deletes fire no child triggers. Records removed by a cascade delete, such as an account's contacts, do not run their own delete triggers. Read them here with a RelatedQuery.
- Merges look like deletes. The records that lose a merge fire before delete like a plain delete.
MasterRecordIdis set only in AfterDelete.
