Monday, 2 December 2013

avoid recursive trigger salesforce

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:
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 = 'testemail@kmail.com';
 update conRec;
 }
}
As you can see the trigger is getting called on after update and as the trigger has a DML update statement on the same object, same trigger will be called again leading to recursion.
To avoid this, just create one global class with a static global boolean variable as below.
global Class recusrssionPreventController{
Global static boolean flag = true;
 Public recusrssionPreventController(){
 }
}
And set this boolean variable in your trigger and then set this boolean variable to false as done in the trigger below
trigger recursiveTrigger on Contact (after update) {
Id recordId ;
if(
recusrssionPreventController.flag == true){
   
recusrssionPreventController.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 = 'testemail@kmail.com';
 update conRec;
 }
}
This will call the trigger only once and hence avoid recursion.

salesforce best practices for developers

Coding in apex requires that you follow all the best practices, as you may hit the governers limit imposed by salesforce.
Let us discuss some of the best practices that you should follow in order to avoid production failures and exceptions
1. Avoid writing select queries within for loop.
   This is something which you should avoid in all cases as this could very easily give "101 soql error"
   You can fire only 100 queries in one instance of apex code run, if more than 100 queries get executed you get the  above exception. Hence write your logic in such a way that you do not use select query within for loop
2. Use collections to store you data in apex, use map list set appropriately.
3.Bulkify your trigger, most often developers write triggers considering only one record would fire the trigger. But, in reality your trigger could be fired by many records at a time. Make sure you write a logic in such a way that it runs considering many records would fire the trigger at a time
4. Clear collections that are no longer required in apex code.Use transient key word where ever possible. View state error can be avoided by doing this.
5. Try to use limit clause in you select query, a select query can return only 50k records.
6. sosl query can return only up to 2000 records hence before using sosl you have to be 100% sure that the returned records will be less in number.
7. No dmls within for loop.
  Avoid updating,inserting or any other dmlon records in for loops. Instead run your dmls on collections. You can issue only 150 dml statements.
8. Write your code logic with minimum statements. Try to reduce number of lines of apex code if possible.
  There's limit for number of lines too.
9. Do not write your logic in trigger, write it in a class method and call that method in trigger.
10. Use access modifiers appropriately.
11. try to re-use code that has been already developed
12. Put your code in try and catch blocks appropriately and catch the exceptions
13. Follow this: One object, one trigger.
14. Follow naming conventions throughout your org, this keeps your codes organised and easily understandable.
15. Develop generic components for functionality that are used in many vf pages.
16. For Test coverage, make sure all the triggers in your org are covered with at least 1%.
    Total coverage needs to be > 75%, classes can have 0% but trigger should have minimum of     1%

get all objects in salesforce org

In order to get all the object names in your org, use Schema.getGlobalDescribe() method. This would return a map of object names and object types. Keyset would be all the object names. Following visualforce page uses this method to display all the objects in an org.



Visualforce page
<apex:page controller="AllObjectsinOrg">
 <apex:form >
   <apex:pageBlock id="pgblck">
    <apex:outputlabel value="Object Name" for="ObjPickList"/>      
    <apex:selectList value="{!ObjectSelected}" multiselect="false" id="ObjPickList" size="1">
       <apex:selectOptions value="{!ObjList}"/>
    </apex:selectList>
 </apex:pageBlock>
 </apex:form>
</apex:page>

Controller
public class AllObjectsinOrg {
 Public string ObjectSelected{get;set;}
 Public Map<String, Schema.SObjectTypeAllObjmap;
 Public AllObjectsinOrg(){
    AllObjmap = New Map<String, Schema.SObjectType>();
    AllObjmap = Schema.getGlobalDescribe();
    System.debug('******All object Names :'+ AllObjmap.keyset());
}
Public List<selectoption> getObjList(){
    List<selectoption> objList = new List<selectoption>();
    for(string s:AllObjmap.keyset()){
        objList.add(new selectoption(s,s));
    }
  return objList;   
 }
}

Salesforce Tools

Some good tools for developers

Salesforce Force.com Explore: 

This is the very first tool which comes in my mind for salesforce.com developers. Its a tool where you can explore salesforce Meta Data ( standard / custom objects, field and others.). I think as of now its best tool to write and execute SOQL queries. You can view your query history and export data to your m/c too.

Write / execute and test your SOQL queries in this tool before adding it to your apex code:

Download salesforce Force.com Explore : 

Installation Guide :

http://wiki.developerforce.com/page/ForceExplorer

Make sure you have Adobe AIR installed
Then download the latest release of Force.com Explorer 



Force.com IDE: 

The Force.com IDE is a full-featured, Eclipse-based coding environment, with capabilities like code completion, version control, collaborative development, and project sharing. 

Using this plugin, development, maintain code become very easy. Also you can deploy code&metadata ( like email templates, reports, objects etc) from your Sandbox to production easily. ( note: deployment activities varies from one Org/individual to other. There are different ways to deploy to production e.g. ANT, Eclipse Force.com plugin or salesforce application deployment interface ).

http://wiki.developerforce.com/page/Force.com_IDE_Installation

Workbench :   

Workbench is a powerful, web-based suite of tools designed for administrators and developers to interact with Salesforce.com.  


https://workbench.developerforce.com/login.php


http://wiki.developerforce.com/page/Workbench


Force.com Data Loader:

Using this tool you can export and import data out of salesforce.com instance. This tool is very much used by SFDC admins and developers for data import and export tasks.

you can download the Data Loader from the SFDC Setup menu, under Administration Setup - Data Management. 
find more details on :
http://wiki.developerforce.com/page/Data_Loader

APEX Class with/without sharing keyword

With or Without Sharing Keywords with APEX class  :

Generally Apex code executes in System contexts, means Access to  all objects,fields and records etc.
(beyond current users permissions, field level security or sharing settings).

(Where do I find "Sharing Settings"? its under "Setup" => "Administration Setup" => "Security Controls" => "Sharing Settings") Know More about "Salesforce Sharing Settings"

Note: ( Exception ) Anonymous code blocks always execute with current user permissions :)

So take care while developing code that user doesn't see/process data which he is not suppose to.
E.g. declaring apex class method as webservice ( take a look , kind of data you process or return inside webservice apex method ).
Give suitable access for class ( to suitable profiles) , once accessed by webservice call, then APEX executes in system context.

:) But this is also possible to execute Apex Class with current user's "Sharing settings". using "With Sharing" keyword. ( consider salesforce sharing setting while executing Apex code )

Note: "With sharing" keyword doesn't enforce the user's permissions and field-level security.

E.g.

public with sharing class MyNewClassWithSharing {
// Code here
}

Use the without sharing keywords means sharing rules for the current user are not enforced. For example:

public without sharing class MyNewClassWithOutSharing {
// Code here
}


Points to be noted:
A)  If with or without sharing are not mentioned with class then default is "Without sharing".

B)  If the class is defined with NO "sharing type" and called with in other class then it will execute with calling class's sharing setting accordingly.
    Else executes with with its own settings.
   
B)  The sharing setting applies to all code contained with in the class, including initialization code, constructors, and methods.

C)  Classes inherit this setting from a parent class when one class extends or implements another.

D)  Inner classes do not inherit the sharing setting from their container class.

E)  Class declared as with sharing can call code that operates as without sharing

F)  All SOQL or SOSL queries that use PriceBook2 ignore the with sharing keyword

G)  Using with sharing keyword :
i) SOQL and SOSL queries, may return fewer rows
ii) DML operation may fail due to insufficient privileges for current user.