2

I am trying to write a simple trigger that adds a sequence number to a list of child activities based on the date the activity is scheduled for. Basically I want to get all Activity__c records for each parent object Parent__c, based on their Scheduled_Date__c fields I will add a sequence number to the field Activity_Sequence__c (i.e. 1, 2, 3, 4, etc.)

THIS HAS BEEN FIXED, SEE BELOW FOR NOW WORKING CODE

trigger ActivitySequence on Activity__c (after insert, after update) {
//create a list of activities to update
List<Activity__c> activitiesToUpdate = new List<Activity__c>();
//Parent Ids
Set<Id> parentIds = new Set<Id>();
//List of Parents
List<Parent__c> parentListById = new List<Parent__c>();

if(!activitySequence.hasAlreadyCreatedSequence())
{ 

  for(Activity__c vo: Trigger.New)
  {
    //add all parent object ids that have activities into the Set
    parentIds.add(vo.Parent__c);
  }

    if(parentIds.size() > 0)
    {    
      //create a list of Parents and children
      parentListById = [SELECT Id, (SELECT Id, Activity_Sequence__c, Scheduled_Date__c FROM Activities__r ORDER BY Scheduled_Date__c) FROM Parent__c WHERE Id IN :parentIds];                             
    }

    if(parentListById.size() >0)
    {
        //get each parent in the list
        for(Parent__c cs: parentListById)
        {
          integer idx = 0;

          //get the child activities for each parent in the list
          for(Activity__c ac: cs.Activities__r)


             {
                ac.Activity_Sequence__c = '(' + idx + ')';
                activitiesToUpdate.add(ac);
                idx = idx+1;       
              }
            }
        activitySequence.setAlreadyCreatedSequence();

        update activitiesToUpdate;
    }

    }

}

And here's my class to prevent recursive trigger

 //public class to stop recursive trigger

public class activitySequence {

    private static boolean alreadySequencedActivities = false;

    public static boolean hasAlreadyCreatedSequence() {
        return alreadySequencedActivities;
    }

    public static void setAlreadyCreatedSequence() {
        alreadySequencedActivities = true;
    }

}

1 Answer 1

1

You are getting duplicate id in list because of the following:

for(EXObject__c w: exList) {
   while(i<=listSize){
     w.Activity_Sequence__c = '(' + i + ' of ' + listSize + ')';
     newList.add(w); // !! if listsize > 1, then w's id is same!
     i++;
   }
}

update newList;

You have two loops, the first for loop goes through all retrieved ExObject__c and the inner while loop goes through them again! Thus if you retrieve more than one ExObject__c, you will add the same object to newList more than once and hence the duplicate ids

  1. Use IN, not = in the SOQL when using collection bind variables
  2. After you update newList, your trigger will be called again (and probably again and again). Resolve this by looking at Preventing Recursive Triggers recipe

The above won't per se solve your business application problem but, in conjunction with diligent use of system.debug statements, you should be able to diagnose your code.

1
  • thank you @crop1645 . I found the tutorial very helpful in my understanding of recursive triggers.
    – rwegner7
    Jan 21, 2015 at 16:45

You must log in to answer this question.

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