Saturday, 14 May 2022

Triggers

 Triggers

Apex can be invoked by using triggers. Apex triggers enable you to perform custom actions before or after changes to Salesforce records, such as insertions, updates, or deletions. Use triggers to perform tasks that can’t be done by exploitation of the point-and-click tools within the Salesforce computer program.

Types of Apex Triggers:

1.      Before Trigger: - Before trigger can be used to update or validate values of a record before they are saved to database.

2.      After Trigger: - It can be used to access field values of the records that are stored in the database and use these values to make changes in other records.

Syntax:

trigger TriggerName on ObjectName (trigger_events) {

                 //    code_block

                     }

where trigger_events can be a comma-separated list of one or more of the following events:

1.   Before insert

2.   Before Update

3.   Before Delete

4.   After insert

5.   After Update

6.   After Delete

7.   After Undelete

 Trigger Context Variable :

 

Variables

Uses

Is Executing

Returns true if the current context for the Apex code is a trigger, not a Visualforce page, a Web service, or an execute anonymous() API call.

isInsert

Returns true if this trigger was fired due to an insert operation, from the Salesforce user interface, Apex, or the API.

isUpdate

Returns true if this trigger was fired due to an update operation, from the Salesforce user interface, Apex, or the API.

isDelete

Returns true if this trigger was fired due to a delete operation, from the Salesforce user interface, Apex, or the API.

isBefore

Returns true if this trigger was fired before any record was saved.

isAfter

Returns true if this trigger was fired after all records were saved.

isUndelete

Returns true if this trigger was fired after a record is recovered from the Recycle Bin. This recovery can occur after an undelete operation from the Salesforce user interface, Apex, or the API.

new

Returns a list of the new versions of the sObject records.
This sObject list is only available in 
insertupdate, and undelete triggers, and the records can only be modified in before triggers.

newMap

A map of IDs to the new versions of the sObject records.
This map is only available in 
before updateafter insertafter update, and after undelete triggers.

old

Returns a list of the old versions of the sObject records.
This sObject list is only available in 
update and delete triggers.

oldMap

A map of IDs to the old versions of the sObject records.
This map is only available in 
update and delete triggers.

operationType

Returns an enum of type System.TriggerOperation corresponding to the current Operation.

Possible values of the System.TriggerOperation enum are: BEFORE_INSERTBEFORE_UPDATEBEFORE_DELETE,AFTER_INSERT

AFTER_UPDATEAFTER_DELETE, and AFTER_UNDELETE

 

size


The total number of records in a trigger invocation, both old and new.

 

 

 Context Variable Availability for Trigger Events :

 

Events

Trigger.Old

Trigger.OldMap

Trigger.New

Trigger.NewMap

Before Insert

No

No

Yes

No

After Insert

No

No

Yes

Yes

Before Update

Yes

Yes

Yes

Yes

After Update

Yes

Yes

Yes

Yes

Before Delete

Yes

Yes

No

No

After Delete

Yes

Yes

No

No

After Undelete

No

No

Yes

Yes

 

Q1. What does one mean by the bulkifying trigger?

A trigger should be able to handle single record and thousands of records. important point to consider:

1.   Write triggers that operate on collections of sObjects.

2.   Write triggers that perform efficient SOQL and DML operations.

3.   If we will not follow above point we may hit governor limit when records are created/updated/deleted in mass using data loader or other tool.

  

Q2.How is Trigger.New Different from Trigger.newMap?

Trigger.New variable returns the list of sObject which has invoked the trigger and Trigger.NewMap returns the map of ID’s with the newly entered records. NewMap is only available in after insert, before and after the update and after undelete.

Q3.How is Trigger.new different from Trigger.old?

Trigger.New variable returns the list of sObject which has invoked the trigger and Trigger.old returns a list of the older versions of the records which have invoked the trigger. Trigger.Old is only available in update and delete events.

Q4. Can a trigger call a batch class?

Yes, we can call a batch class in the trigger. But Salesforce allows only 5 Batch jobs in the Queue.

Q5. Can a trigger make a call to Apex callout method?

We cannot call the callouts directly from the trigger, instead we will define callouts in the future annotated methods and these future annotated methods can be called from the trigger. We can only do 10 callouts in a single transaction.

Q6. Write a trigger for roll up summary on account object to sum the total contacts associated with an account.

 We have to create a custom field on account with the name "No_Of_Contacts__c".



 Q7. Write a trigger to prevent deletion of Account having contact associated with it.

or,


Q8. Write a trigger to display an error on Contact creation if the Account has more than 2 contacts.

Q9. Write a trigger to get sum of all the opportunities on Account.


First, we will create a custom field on Account “Total_Opportunity_Amount__c”.

 


 

Q10. Write a trigger on Account when type field value changed to “Prospect” else assign value as “Other”.

 

 

Q11. Trigger to create related contact when an account is created and associate that contact with accounts.


Q12. Write a trigger, Whenever the user Updates the Account Record, the Description of the Account Record will be changed to Logged in User Name.


Q13. whenever there is an update in account phone number, the related contact phone number should also get updated.


or



Q14. Apex trigger to update account rating to “Hot”,when the opportunity stage equals closed won.



 

Q15. Write a trigger, whenever new account is created with annual revenue more than 50 lakhs then add Wilson as account team member.




Q16.
When ever a case is created with origin as email then set status as new and Priority as Normal.



Q17. Whenever lead is created with leadSource as Web then give rating as cold otherwise hot.


 

Q18. Whenever opportunity stagename is modified to closed won then set closedate as today and type as new Customer.

  


 Q19. Whenever we are trying to delete the account record which has 

a contacts for it. Then deletion has to fail.

 

 

Q20. What is Recursive Trigger? And how to Avoid it.

 Ans : Recursion is the process of executing the same task multiple times. It can lead to infinite loop and which can result to governor limit sometime. Sometime it can also result in unexpected output or the error “maximum trigger depth exceeded”.

Ex: I’ve a trigger on Account object, which will be execute on before Update and after Update. In after Update I’ve some custom logic to update Account records. So, when I’m updating the Account records in After Update, it is throwing error “maximum trigger depth exceeded”. So, it is a recursion in apex trigger.

 

How to Avoid it:

We can create one static Boolean variable

 

public class AvoidRecursive {
   public static boolean firstRun = true;
}

 

and in trigger we can check the flag:

 

trigger TestTrigger on Contact (after insert) {
    if(AvoidRecursive.firstRun)
    {
        AvoidRecursive.firstRun = false;
        insert new Contact(Lastname=’Madhu’, Phone=12345);
    }  

 

Here first time we set Boolean variable as “TRUE” in class.  In trigger variable is equals to true then it goes to inside loop, performs logic and then variable sets as “FALSE” so next time it will not run (if variable=false then it will not go to loop & will not perform logic). So, if   Code will try to run second time in same request, then it will not run.

 

 There is one more way to avoid recursive trigger.

Create a new RecursiveCheck Class and add a static Set recordIds that will be used to store record Ids from trigger list.

 

Now in Trigger use recordIds set to check for the record ids on which the Trigger has already run like below: 

NOTE : Instead of checking the size before  DML in trigger. I.E

if(list.size().0)
{
//DML statements
}

We should use 

if(!list.isEmpty)
{
//DML statement
}

 It will save lot of resources. if we are using size() method, it will iterate over all the records, but do we really need to iterate over all those records ? NO.

So, Even if , we have 1 record, we need to perform DML, that's why, we should try to use isEmpty instead of size() method.


 Question : Scenario is, we have two objects(it can be standard or custom), both are in lookup relation. We are taking Account and contact objects

on Parent, we have below fields

1. Active_Contacts__c - total no. of contacts associated

2.Recently_completed_milestone__c - Date time field

on contact, we have "status" field.

Whenever status is changing from ongoing to completed, we need to stamp datetime on parent custom field. Also, we need to count no. of contacts associated with Account.

 


 Question : Suppose we have below requirement :

Account object :

Account fields : 

        Name : Salesforce Learners

        SLAserialNumber : SFDC01

        Active_Contacts__c = ?


Candidate object :

   Fields :

 Candidate Name =  Gaurav

SLAserialNumber = SFDC01

Account (lookup to Account) =  ?


Based on SLAserialNUmber( some code), we need to populate account on candidate which is look up to Account object. Also we need to populate number of candidates on Account.


Ans : To populate no. of candidates on Account, we have a custom field(Active_Contacts__c) on Account.

 SLAserialNumber__c is also custom field. It will be unique. we can consider it as code.



Question : Write a trigger to  When a related contact of an Account is created we have to consider following  scenarios:

  1. If the inserted contact is the first contact , then we need to mark it as primary contact for that related Account.

  2. If multiple contacts are already related to an Account, then the first contact which was created for that account has to be marked as  primary contact of the Account.

Solution : We have to create a custom checkbox field on contact as " primary Contact " Primary_Contact__c.


 

 

 

 

No comments:

Post a Comment

Duplicate id in list

  Error 'System.ListException: Duplicate id in list' in Apex : list  can hold  duplicate values, but if you try to add duplicate  sO...