1

I have two records which are related with one field unique_pile_id__c

enter image description here

I need to update unique_id__c value with some unique value based on unique_pile_id__c for that i am writing trigger like this

trigger opMetricsTrigger on Operational_Metrics__c (after insert,after update) 
{
 Operational_Metrics__c[] op=null;
 Set<Id> opIds = new Set<Id>();
 public static boolean run = true;
 if(run)
 {
   run=false;
 for (Operational_Metrics__c e : Trigger.new) 
 {
     if(e.id != null)
     opIds.add(e.id );
 }

 List<Operational_Metrics__c> opm = [select Unique_Pile_ID__c,unique_id__C, Project__c,Composting_Method__c,Pile_Monitoring_Date__c,Average_Temperature__c,Moisture_Test__c,Pile_Monitoring_Action_Taken__c,Other_Action__c,Pile_Input_Register_Date__c,Total_Waste_Input_on_the_Pile__c,Pile_Completion_Stage__c,Date_Pile_COmpleted__c,Curing_Batch_Register_Date__c,No_of_Days__c  from operational_metrics__c where id in :opIds];
 for(Operational_Metrics__c ops :opm)
 {
     if(ops.Pile_Completion_Stage__c=='yes')
     {
         ops.Unique_Id__c=ops.Unique_Pile_ID__c+'-Mir'; 
         System.debug('records1 are '+ops);
     }  
     else
     {
         ops.Unique_Id__c=ops.Unique_Pile_ID__c+'-Mir'; 
         System.debug('records2 are '+ops);
      }
 }
   update opm;
}
}

But while inserting it is throwing error as

Apex trigger opMetricsTrigger caused an unexpected exception, contact your administrator: opMetricsTrigger: execution of AfterUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id a0dK000000aztabIAA; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, opMetricsTrigger: maximum trigger depth exceeded Operational_Metrics trigger event AfterUpdate for [a0dK000000aztab] Operational_Metrics trigger event AfterUpdate for [a0dK000000aztab] Operational_Metrics trigger event AfterUpdate for [a0dK000000aztab] Operational_Metrics trigger event AfterUpdate for [a0dK000000aztab] Operational_Metrics trigger event AfterUpdate for [a0dK000000aztab] Operational_Metrics trigger event AfterUpdate for [a0dK000000aztab] Operational_Metrics trigger event AfterUpdate for [a0dK000000aztab] Operational_Metrics trigger event AfterUpdate for [a0dK000000aztab] Operational_Metrics trigger event AfterUpdate for [a0dK000000aztab] Operational_Metrics trigger event AfterUpdate for [a0dK000000aztab] Operational_Metrics trigger event AfterUpdate for [a0dK000000aztab] Operational_Metrics trigger event AfterUpdate for [a0dK000000aztab] Operational_Metrics trigger event AfterUpdate for [a0dK000000aztab] Operational_Metrics trigger event AfterUpdate for [a0dK000000aztab] Operational_Metrics trigger event AfterUpdate for [a0dK000000aztab] Operational_Metrics trigger event AfterUpdate for [a0dK000000aztab]: []: Trigger.opMetricsTrigger: line 46, column 1

Here line 46, column 1 is update command in the code. could help me out to fix this issue

3 Answers 3

3

You've got a couple issues going on.

First, you should be using a before trigger. While there are some exceptions you never want to be updating a record that is being processed by the trigger using DML statements, as this can lead to trigger recursion. If you use a before trigger you can update the record directly without a DML statement.

Second, while you don't need this after switching to a before trigger, you're "run" variable isn't going to work. Each time you're trigger executes it's reseting the value to true at line 5. Triggers are weird, and aren't really classes, so things like static variables are going to behave strangely, if you're creating functions are variables in triggers you really need to look at moving your logic into an external class that is called from a trigger. Besides being cleaner and a best practice, it'll make things a lot easier to understand in terms of how variables, methods, and functions behave.

2
2

+1 Ralph - you should not be trying to update the same record in the after insert/update. Also triggers should be as light as possible in terms of business logic and simply call a class which handles the actual data manipulation.

This is simple trigger framework which I have used in the past https://github.com/kevinohara80/sfdc-trigger-framework

Don't worry about that for too much now and give this a try:

trigger opMetricsTrigger on Operational_Metrics__c (before insert,before update) 
{

 for(Operational_Metrics__c ops :[SELECT Unique_Pile_ID__c, 
                                          unique_id__C, 
                                          Project__c,
                                          Composting_Method__c,
                                          Pile_Monitoring_Date__c,
                                          Average_Temperature__c,
                                          Moisture_Test__c,
                                          Pile_Monitoring_Action_Taken__c,
                                          Other_Action__c,
                                          Pile_Input_Register_Date__c,
                                          Total_Waste_Input_on_the_Pile__c,
                                          Pile_Completion_Stage__c,
                                          Date_Pile_COmpleted__c,
                                          Curing_Batch_Register_Date__c,
                                          No_of_Days__c  FROM operational_metrics__c where id in :Trigger.new]){

     if(ops.Pile_Completion_Stage__c=='yes'){
         ops.Unique_Id__c=ops.Unique_Pile_ID__c+'-Mir'; 
         System.debug('records1 are '+ops);
     }  
     else
     {
         ops.Unique_Id__c=ops.Unique_Pile_ID__c+'-Mir'; 
         System.debug('records2 are '+ops);
      }
    }

}
0

Like others have said, you need to be using a 'before' trigger. This lets you make changes to a record before it is saved into the database allowing you to get rid of 'update record'.

trigger opMetricsTrigger on Operational_Metrics__c (before insert, before update) 
{
  for(Operational_Metrics__c ops: Trigger.new)
  {
  if(ops.Pile_Completion_Stage__c == 'yes')
  {
    ops.Unique_Id__c = ops.Unique_Pile_ID__c + '-Mir'; 
    System.debug('records1 are ' + ops);
  }  
  else
  {
    ops.Unique_Id__c = ops.Unique_Pile_ID__c + '-Mir'; 
    System.debug('records2 are ' + ops);
  }
}

On a side note, you also had a couple other things wrong with your trigger. NEVER do a DML statement instead of a loop. Add them to a list then update the whole list instead. Also, try to use just a single trigger class and pass the actual work into some sort of helper methods. There are some great frameworks out there to help with this as well, but you don't have to get as complex as that.

You must log in to answer this question.

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