Skip to content

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 unitOfWork from 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 insert here skips the unit of work.