Thursday, November 22, 2012

Prevent Recursion of Trigger Execution in Salesforce - Part2




Salesforce – Stop Recursion of Trigger Execution- <Method-2>
As per my previous post , the method-2 for preventing recursive trigger execution in salesforce  is

Method (2) : Add a new field to the object so the trigger can inspect the record to see if it is being called by the future method.

The trigger checks the value of IsFutureExecute__c in the list of Accounts passed into the trigger. If the IsFutureExecute__c value is true then the trigger is being called from the future method and the record shouldn’t be processed. If the value of IsFutureExecute__c is false, then the  trigger is being called the first time and the future method should be called and passed the Set of unique names.

trigger updateSomething on Account (before insert, before update) {
     Set<Id> idsToProcess = new Se<Id>();
     for (Account acct : Trigger.new) {
          if (acct.IsFutureExecute__c) {
               acct.IsFutureExecute__c = false;
          } else {
              if(acct.NumberOfEmployees > 500){
                idsToProcess.add(acct.Id);
            }
          }
     }
     if (!idsToProcess.isEmpty())
          AccountProcessor.processAccounts(idsToProcess );
}

The AccountProcessor class contains the static method with the future annotation i.e called by the trigger. The method processes each Account and sets the value of IsFutureExecute__c to false before committing. This prevents the trigger from calling the future method once again.

public class AccountProcessor {

     @future
     public static void processAccounts(Set<ID> Ids) {
          // list to store the accounts to update
          List<Account> accountsToUpdate = new List<Account>();
          // iterate through the list of accounts to process
          for (Account a : [Select Id, Name, IsFutureExecute__c From Account where ID IN :Ids]) {
               // ... do you account processing
               // set the field to true, since we are about to fire the trigger again
               a.IsFutureExecute__c = true;
               // add the account to the list to update
               accountsToUpdate.add(a);
          }
          // update the accounts
          update accountsToUpdate;
     }

}

Tuesday, May 29, 2012

Assignment rule in a trigger

                                   
The objective is to have assignment rules to be fired on a  record creation. 
But, the assignment rule only can be fired on UPDATE operation inside the trigger.
Because when we try to perform DML operation in trigger.new or trigger.old , It throws exception

"Execution of AfterInsert caused by: System.SObjectException: DML statment cannot operate on trigger.new or trigger.old:"

The rule can be assigned only when using "update" DML in an "after insert" trigger.
So the logic should be  in AFTER trigger collect the record Ids , and then SELECT the records & try to UPDATE the same .


trigger caseAssignment on Case (after insert) {

        List<Id> caseIds = new List<Id>{};
        for (Case caseObj:trigger.new)
            caseIds.add(caseObj.Id);
     
        List<Case> caseList = new List<Case>{};
        for(Case myCase : [Select Id from Case where Id in :caseIds])
        {
            Database.DMLOptions dmo = new Database.DMLOptions();

            dmo.assignmentRuleHeader.useDefaultRule = true;
            myCase.setOptions(dmo);
         
            caseList.add(myCase);
        }
        Database.upsert(caseList);
}