AfterUndelete
Runs in after undelete, after records are restored from the Recycle Bin. Change other records with a Writer or start async work with a Dispatcher.
Roles
- Writer: create, update or delete other records through a unit of work.
- Dispatcher: make one bulk call per chunk, such as enqueueing a Queueable.
Add-ons
- ParentQuery: load parent (lookup) fields before the first handler runs; read them with
getNewParent. - RelatedQuery: query children, siblings or any other records once per chunk; read them with
getRelated. - OwnUnitOfWork: give the handler its own unit of work, committed right after it. Writer only.
- 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.AfterUndelete on the orchestrator and return the handlers from afterUndeleteHandlers(). List order is run order. The trigger must list after undelete and call TriggerOrchestrator.run(new ContactTriggerOrchestrator()).
apex
public with sharing class ContactTriggerOrchestrator implements TriggerOrchestrator.AfterUndelete {
public List<AfterUndelete.Handler> afterUndeleteHandlers() {
return new List<AfterUndelete.Handler>{ new ContactWriter(), new ContactDispatcher() };
}
}Good to Know
- No Validator. Salesforce has no before undelete event. To block a restore, call
record.getNewSObject().addError(…)from a Writer or Dispatcher and list that handler first. The record stays in the Recycle Bin. - The restored row is read-only. Writing to
getNewSObject()throws aFinalExceptionthat nocatchstops. To change the record, registerunitOfWork.toUpdate(new Account(Id = record.getId(), …)). That fires BeforeUpdate and AfterUpdate again. - Lookups hold only the Id.
((Contact) record.getNewSObject()).Accountis null. Declare a ParentQuery and readrecord.getNewParent('Account'). - Only the top-level record's trigger runs. Salesforce restores cascade-deleted children with their parent, but runs only the parent's after undelete trigger. Handle the children from the parent's handlers.
- Called per chunk.
afterUndeleteHandlers()runs for every chunk of up to 200 records. Restoring 1,000 records means 5 runs and 5 Dispatcher calls.
