Tuesday, June 27, 2017

Triggers in salesforce:

Interview questions on triggers In salesforce

1.What is trigger ?
Ans: Trigger is piece of code that is executes before and after a record is Inserted/Updated/Deleted from the force.com database.

2.What are different types of triggers in sfdc?
Ans: 1.Before Triggers-These triggers are fired before the data is saved into the database.
2.After Triggers-These triggers are fired after the data is saved into the database.

3.What are trigger context variables?
Ans:
Trigger.isInsert: Returns true if the trigger was fired due to insert operation.
Trigger.isUpdate: Returns true if the trigger was fired due to update operation.
Trigger.isDelete: Returns true if the trigger was fired due to delete operation.
Trigger.isBefore: Returns true if the trigger was fired before record is saved.
Trigger.isAfter: Returns true if the trigger was fired after record is saved.
Trigger.New: Returns a list of new version of sObject records.
Trigger.Old: Returns a list of old version of sObject records.
Trigger.NewMap: Returns a map of new version of sObject records. (map is stored in the form of map)
Trigger.OldMap: Returns a map of old version of sObject records. (map is stored in the form of map)
Trigger.Size: Returns a integer (total number of records invoked due to trigger invocation for the both old and new)
Trigger.isExecuting: Returns true if the current apex code is a trigger.
What are the difference between trigger.new and trigger.old?
Ans: 
Trigger.new 
 1. Returns the new version of sObject records
 2. Available only in insert and update events
 3. Records can be modified only in before events

Trigger.old
 1. Returns the old version of sObject records 
 2. Available only in update and delete events


6.What is the difference between Trigger.New and Trigger.Old in update triggers?
Ans:

7.Can we call batch apex from the Trigger?
Ans: A batch apex can be called from a class as well as from trigger code.
In your Trigger code something like below :-
// BatchClass is the name of batchclass
BatchClass bh = new BatchClass();
Database.executeBacth(bh);

8.What are the problems you have encountered when calling batch apex from the trigger?
Ans:

You can call a batch from a trigger, but you need to be aware of potential limits you could hit.
 You can only have 5 batch jobs queued or executing at once. If your trigger calls batch jobs each 
time, then you could quickly exceed that limit

9.Can we call the callouts from trigger?
Ans: yes we can. It is same as usual class method calling from trigger. The only difference being the method should always be asynchronous with @future

10.What are the problems you have encountered when calling apex the callouts in trigger?
Ans:

11.What is the recursive trigger?
Ans: Recursion occurs in trigger if your trigger has a same DML statement and the same dml condition is used in trigger firing condition on the same object(on which trigger has been written)

How to restrict a trigger to run only once? (How to avoid recursive trigger execution?)

Ans: Triggers can fire twice, once before workflow rules and once after workflow rules. The before and after trigger fire one more time only if something needs to be updated. 

To avoid recursive execution of triggers, we need to have the code write something like below.

 public class HelperClass{
     public static boolena firstRun = true;
 }

 trigger Xtrigger on Account(before delete, after delete){
      if(Trigger.isBefore){
          if(Trigger.isDelete){
              if(HelperClass.firstRun){
                  Trigger.old[0].addError('Before Delete Error');
                  HelperClass.firstRun = false;
              }    
          }
      }
 }

12.What is the bulkifying triggers?
Ans: By default every trigger is a bulk trigger which is used to process the multiple records at a time as a batch. For each batch of 200 records.

13.What is the use of future methods in triggers?
Ans: Using @Future annotation we can convert the Trigger into a Asynchrinous Class and we can use a Callout method.

14.What is the order of executing the trigger apex?
Ans:
1. System Validation Rules
2. All Apex “before” triggers
3. Custom Validation Rules
3. Executes all after triggers.
4. Executes assignment rules.
5. Executes auto-response rules.
6. Executes workflow rules.
7. If there are workflow field updates, updates the record again.
8. If the record was updated with workflow field updates, fires before and after triggers one more time. Custom validation rules are not run again.
9. Executes escalation rules.
10. If the record contains a roll-up summary field or is part of a cross-object workflow, performs calculations and updates the roll-up summary field in the parent record. Parent record goes through save procedure.
11. If the parent record is updated, and a grand-parent record contains a roll-up summary field or is part of a cross-object workflow, performs calculations and updates the roll-up summary field in the parent record. Grand-parent record goes through save procedure.
12. Executes Criteria Based Sharing evaluation.
13. Commits all DML operations to the database.
14. Executes post-commit logic. Ex: Sending email.

15.
What is the trigger handler?
Ans:

16.How do we avoid recursive triggers?
Ans: Use a static variable in an Apex class to avoid an infinite loop. Static variables are local to the context of a Web request.

17.
How many triggers we can define on a object?
Ans: We can write more than one trigger But it is not recommended .Best practice is One trigger On One object. 

18.Can we define triggers with same event on single object?
Ans:

19.Tell me more scenarios where you have written triggers?
Ans:

20.What is the best scenario that you have developed on triggers?
Ans:

21.How many time workflow filed update will be called in triggers?
Ans:


Why 1% coverage is mandatory for triggers in salesforce?

Ans: This is to make sure that the triggers written will be executed in the production environment and will not become unreachable code and trigger actions are called when appropriate actions are done.

Trigger Handler Patterns In salesforce?


There's no defined pattern as such but it is always considered as a best practice to have all your trigger logic inside one handler class and only have one trigger on each object.

Example Trigger
An Apex Trigger should be written so that every operation calls a method in an external Apex Class. By doing so code can easily be added or removed, and variables can be used multiple times without additional queries to the database.

Apex Trigger:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
trigger objectTrigger on Object (after delete, after insert, after undelete, after update, before delete, before insert, before update) {
    objectTriggerHandler handler = new objectHandler();
    /* Before Insert */
    if(Trigger.isInsert && Trigger.isBefore){
        handler.OnBeforeInsert(Trigger.new);
    }
    /* After Insert */
    else if(Trigger.isInsert && Trigger.isAfter){
        handler.OnAfterInsert(Trigger.new);
    }
    /* Before Update */
    else if(Trigger.isUpdate && Trigger.isBefore){
        handler.OnBeforeUpdate(Trigger.old, Trigger.new, Trigger.newMap);
    }
    /* After Update */
    else if(Trigger.isUpdate && Trigger.isAfter){
        handler.OnAfterUpdate(Trigger.old, Trigger.new, Trigger.newMap);
    }
    /* Before Delete */
    else if(Trigger.isDelete && Trigger.isBefore){
        handler.OnBeforeDelete(Trigger.old, Trigger.oldMap);
    }
    /* After Delete */
    else if(Trigger.isDelete && Trigger.isAfter){
        handler.OnAfterDelete(Trigger.old, Trigger.oldMap);
    } 
    /* After Undelete */
    else if(Trigger.isUnDelete){
        handler.OnUndelete(Trigger.new);
    }
}

Example Trigger Handler Class
The Apex Trigger template above calls a handler class to execute the trigger logic, the trigger handler class should be defined as follows:
Trigger Handler Class:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public with sharing class ObjectTriggerHandler {
    private boolean m_isExecuting = false; 
    public ObjectTriggerHandler(boolean isExecuting){
        m_isExecuting = isExecuting;
    } 
    public void OnBeforeInsert(Object[] newObjects){
        // EXECUTE BEFORE INSERT LOGIC
    } 
    public void OnAfterInsert(Object[] newObjects){
        // EXECUTE AFTER INSERT LOGIC
    }
    public void OnBeforeUpdate(Object[] oldObjects, Object[] updatedObjects, MapObjectMap){
        // BEFORE UPDATE LOGIC
    } 
    public void OnAfterUpdate(Object[] oldObjects, Object[] updatedObjects, MapObjectMap){
        // AFTER UPDATE LOGIC
    } 
    public void OnBeforeDelete(Object[] ObjectsToDelete, MapObjectMap){
        // BEFORE DELETE LOGIC
    } 
    public void OnAfterDelete(Object[] deletedObjects, MapObjectMap){
        // AFTER DELETE LOGIC
    } 
    public void OnUndelete(Object[] restoredObjects){
        // AFTER UNDELETE LOGIC
    } 
    public boolean IsTriggerContext{
        get{ return m_isExecuting;}
    }
}
Recursive trigger in salesforce and how to avoid it?
Recursion occurs when the code gets called again and again and goes into a infinite loop. It is always advisable to write a code that does not call itself. However, sometimes we are left with no choice. Recursion occurs in trigger if your trigger has a same DML statement and the same dml condition is used in trigger firing condition on the same object(on which trigger has been written)
For example, if your trigger fires on after update on contact and you update any contact record in your trigger then the same trigger will be called and will lead to a infinite loop.
To avoid this kind of recursion and call the trigger only once we can use global class static variable.
As an example let says you have following trigger on contact:
?
1
2
3
4
5
6
7
8
9
10
11
trigger recursiveTrigger on Contact (after update) {
Id recordId ;
 for(contact con : trigger.new){
     recordId = con.id;
 }
 Contact conRec =[select id,name,email from contact where id !=: recordId limit 1];
 conRec.email = 'test@test.com';
 update conRec;
 }
}




?
1
2
3
4
5
global Class recusrssionPreventController{
Global static boolean flag = true;
 Public recusrssionPreventController(){
 }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
trigger recursiveTrigger on Contact (after update) {
Id recordId ;
if(recusrssivePreventController.flag == true){
   recusrssivePreventController.flag = false;
 for(contact con : trigger.new){
     recordId = con.id;
 }
 Contact conRec =[select id,name,email from contact where id !=: recordId limit 1];
 conRec.email = 'test@test.com';
 update conRec;
 }
}

What is the  maximum trigger depth exceeded exception in salesforce?

When you are creating an Apex code that recursively fires triggers due to insert/update/delete statement for more than 16 times. You will get the Maximum Trigger Depth Exceeded error.

The following example will demonstrate this issue:

trigger cloneAnotherAcc on Account (before insert) {
Account acc = new Account(name=’Clone me’);
insert acc;
}

This trigger will end up in an infinite loop.

In order for you to solve this issue, you can set a condition on insert so it will not be called recursively. Set a flag to manage the insert trigger will be the ideal. To do this, you need to create a new class to keep track the number of times of insert or stop the insert process on second time.

global class triggerCount {
static integer runTimes = 0;

public static integer getRunTimes(){
return runTimes;
}

public static void setRunTimes(){
runTimes++;
}
}

Once you successfully create this class, you can implement this triggerCount class on your trigger to limit the number of times for insert.

trigger createAcc on Account (before insert) {
if(triggerCount.getRunTimes < 2){
Account acc= new Account(name=’Clone me’);
triggerCount.setRunTimes();
insert acc;
}
}

How to compare old field value with the New field value in Salesforce?


Here you can compare the values with  trigger.oldMap . Here is the sample example on contact email field.

trigger Email_Check_On_Contact on Contact (before update) {
  Map<Id,Contact> o = new Map<Id,Contact>();
    o = trigger.oldMap;
    for(Contact newcont: trigger.new)
    {
      
        if(newcont.Email != o.get(newcont.Id).Email)
        {
            newcont.Email.addError('Email cannot be changed');
        }
    }
}
How to execute Batch Apex Using Apex Trigger?

Hi,
In this post i am trying to give an example of how to execute Batch Process from Apex Trigger. Here i am calling Batch class from the trigger.

Trigger:

trigger UpdateAreaInfoUser on User (after update)  {
Map<id, User> owners = new Map<id, User>();

for (Integer i=0;i<Trigger.new.size();i++) {
if (Trigger.new[i].Team__c!=Trigger.old[i].Team__c) {
owners.put(Trigger.new[i].Id, Trigger.new[i]);
}
}

// You can execute batch apex using trigger using below codes
if (owners.size() > 0) {
Database.executeBatch(new UpdateAccountArea(owners));
}

}

Batch Apex Class:

global class UpdateAccountArea implements Database.Batchable<sObject> {
//map of userid - user
Map<Id, User> ownerMap = new Map<Id, User>();

//Constructor initialization
global UpdateAccountArea(Map<Id, User> owners) {
ownerMap = owners;
}

//Quuery method.
global Database.QueryLocator start(Database.BatchableContext BC) {
return DataBase.getQueryLocator([SELECT Id,Area__c, OwnerId FROM account WHERE OwnerId IN : ownerMap.keySet()]);
}

//Execute Method.
global void execute(Database.BatchableContext BC,List<Account> scopeAcc) {

for (Integer i=0;i<scopeAcc.size();i++){
scopeAcc.get(i).Area__c=ownerMap.get(scopeAcc.get(i).OwnerId).Team__c;
}
update scopeAcc;
}

//Finish method to execute at last.
global void finish(Database.BatchableContext BC) {
//Send an email to the User after your batch completes
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
String[] toAddresses = new String[] {'sfdcsrini@gmail.com'};
mail.setToAddresses(toAddresses);
mail.setSubject('Apex Batch Job is done');
mail.setPlainTextBody('The batch Apex Job Processed Successfully');
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}
}

How Insert new case comment using Apex Trigger in salesforce?


Hi,
In this post i am trying to give a trigger example of creating case comments while creating case.

Task: I need to insert the CaseComment to all the Relevant Cases whenever New casecommnet is created or updated Using Trigger,

Trigger:

trigger updateCaseComment on CaseComment(after insert, after update) {
Map<Id,CaseComment> caseMap = new Map<Id,CaseComment>();

for (CaseComment t: Trigger.new){

caseMap.put(t.ParentId,t);
}

Set<Id> idSet = caseMap.keySet();
List<Case> allCases = [select Id,ParentId from Case where ParentId in :idSet];
List<CaseComment> childCommand = new List<CaseComment>();

for(integer i=0;i<allCases.size();i++){ 

CaseComment newCommmand = new CaseComment();
newCommmand.CommentBody = caseMap.get(allCases[i].ParentId).CommentBody;
newCommmand.IsPublished = TRUE;
newCommmand.ParentId = allCases[i].id;
childCommand.add(newCommmand);
}

if(!childCommand.isEmpty()){
insert childCommand;
}

}

1 comment:

  1. Thanks admin, your blog is really helpful to me. Share more interview questions like this. I have bookmarked this page for my future reference.
    Salesforce Course in Chennai | Salesforce Training in Chennai

    ReplyDelete