I have two objects which have a lookup relationship.

Object 1 - Task

Object 2 - Bonus__c

When a task is updated to 'Completed', I am creating a Bonus__c record.

How to update the lookup field on Task with Bonus__c value once the bonus record is created ?

Here's my code in the Task trigger Handler (afterUpdate)-

protected override void afterUpdate() {

public static void createBonusRecord () {    

List<Bonus__c> bonusToInsert = new List<Bonus__c>();
for (Task t : (List<Task>) Trigger.new) {
      if(t.Status = 'Completed') { 
         Bonus__c bonus = new Bonus__c();
         bonus.Stage__c = 'Evaluation';
         bonus.Type__c = 'Annual';
         bonus.Account__c = t.WhatId;
         bonus.Manager__c = t.OwnerId; 
 if(!bonusToInsert.isEmpty()) { 
 // Update Bonus lookup field on Task with the newly created record ? 

  • 1
    What part of this isn't working for you? What have you tried and what errors are you seeing?
    – Nick C
    Apr 28, 2022 at 1:34

1 Answer 1


Looks like you are using fflib here ... (if not, my solution is only a guide)

There are two parts to this issue

  1. Updating the Task.Bonus__c field to the newly-created Bonus__c

  2. Avoiding recursion in this trigger after you update the Task record from #1

    static Set<Id> visitedTasksAssignedBonuses = new Set<Id> ();
    for (Task t :  Trigger.new) {
      if(!visitedTasksAssignedBonuses.contains(t.Id) && t.Status == 'Completed') { 
         Bonus__c bonus = new Bonus__c (
             Stage__c = 'Evaluation';
             Type__c = 'Annual';
             Account__c = t.WhatId;
             Manager__c = t.OwnerId; 
         uow.registerDirty(t,Task.Bonus__c,bonus); // sets relationship field


  1. You were missing the == in your if test
  2. fflib_SObjectUnitOfWork is bulkified and you don't need to call the registerXXX methods with lists - in fact, if using ApexMocks, it is simpler to do assertions on individual sobjects rather than lists as otherwise the syntax gets unwieldy and the apexmocks output when an assertion fail is harder to interpret.
  3. Your Application.UnitOfWork value needs to be sure to have Bonus__c ahead of Task in the ordered list of SobjectTypes. This is best practice - parents (e.g. Bonus__c) get DML before children (Task) - though in your case, fflib_SobjectUnitOfWork does inserts before updates.
  4. The set of Ids is used to avoid recursion; there's an fflib_SobjectDomain alternative that shuts off the trigger handler for Tasks - see this blog post for how to use

This site is temporarily in read-only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .