AfterInsert.Finalizer
Runs once after a Writer or Dispatcher has processed the chunk, with the records that qualified. Use it for one write per parent instead of one per record.
Interface
apex
public class AfterInsert {
public interface Finalizer {
void finalizeAfterInsert(TriggerHandler.InsertRecords records);
}
}finalizeAfterInsert(records): called once per chunk, after this handler’s records, only if at least one record qualified; after the dispatch for a Dispatcher. It receives only the qualified records.
Example
apex
public with sharing class ContactWriter implements AfterInsert.Writer, AfterInsert.Finalizer {
private TriggerHandler.UnitOfWork unitOfWork;
public Boolean writeOnAfterInsertWhen(TriggerHandler.InsertRecord record) {
return record.isNotNull(Contact.AccountId);
}
public void writeOnAfterInsert(TriggerHandler.InsertRecord record, TriggerHandler.UnitOfWork unitOfWork) {
this.unitOfWork = unitOfWork;
unitOfWork.toInsert(new Task(WhatId = ((Contact) record.getNewSObject()).AccountId, Subject = 'Review contact'));
}
public void finalizeAfterInsert(TriggerHandler.InsertRecords records) {
for (Id accountId : records.getIdsOf(Contact.AccountId)) {
this.unitOfWork.toUpdate(new Account(Id = accountId, Description = 'Contacts changed'));
}
}
}Good to Know
- Keep the unit in a field. The Finalizer gets no unit of work. Save the
unitOfWorkfrom the action in an instance field, as the Skeleton does. - Not once per statement. A 1,000-record insert can call it 5 times.
- Registrations commit with the rest. An own or private unit commits right after the Finalizer. The shared unit commits after the last handler.
- Don't empty the list.
records.getRecords()is the library's own list. When it ends up empty, the Writer's own or private unit is not committed. - Direct DML runs at once. After insert has no DML guard, so an
inserthere skips the unit of work.
