Wednesday, 15 August 2012

Handling Recursive Calling in Trigger


Here  i wrote two triggers on account and contact  with names called continsert on account and accountupdate  on contact


in continsert trigger i am inserting contact with name of Account  at the time of update

in accountupdate trigger i am updating account  at the time of contact insertion


See the below triggers:
-------------------------------------
1)Trigger on Account to insert a contact when account is update

trigger continsert on Account (after update) {
        List<contact> lstcontact=new List<Contact>();
       for(Account acc:Trigger.new){
               Contact cnt=new Contact();
               cnt.lastname=acc.name;
               cnt.accountid=acc.id;
               lstcontact.add(cnt);     
       }
       if(lstcontact!=null && lstcontact.size()>0){
                             insert lstcontact;
                        
        }
}

2)Trigger on Contact to update the account when contact is inserted

trigger accountupdate on Contact (after insert) {
    List<Account> lstaccount=new List<Account>();
    for(Contact c:Trigger.new){
            if(c.accountid!=null){
                Account acc=new Account(id=c.accountid);
                acc.description='contact is created with name:'+c.lastname;
                lstaccount.add(acc);
            }
   
    }
    if(lstaccount!=null && lstaccount.size()>0){
                     update lstaccount;
       }

}


Now when i am  trying to insert contact  then account will update  then continsert on account is also fired with accountupdate on contact because here in accountupdate trigger we are updating account.
When i am trying to update an account then contact is inserting then accountupdate on contact is alsos fired with continsert trigger on account because here in continsert trigger we are inserting contact.

So it throws an error and it is because of recursive calling.

To Avoid or Remove the recursive calling from above  triggers  please follow the following instructions
=========================================================================

So to avoid recurive calling we need to write a class with static boolean variable and use it at the DML statements on both triggers.

see the below code for recursiveavoid class with boolean variable and modified triggers by using boolean variable at the DML statements.

Please use the same as i am  explaining in your recurive trigger Message update and Autotaskupdate some thing

class with boolean variable:
===================
public class recursiveavoid{
    public static boolean recursive=false;
}

See the below triggers:
-------------------------------------
1)Trigger on Account to insert a contact when account is update

trigger continsert on Account (after update) {
        List<contact> lstcontact=new List<Contact>();
       for(Account acc:Trigger.new){
               Contact cnt=new Contact();
               cnt.lastname=acc.name;
               cnt.accountid=acc.id;
               lstcontact.add(cnt);     
       }
//Here i am using boolean variable  called "recursive" to avoid reursive calling from trigger to another trigger
       if(lstcontact!=null && lstcontact.size()>0 && recursiveavoid.recursive==false){
               recursiveavoid.recursive=true;
               insert lstcontact;
           
              
        }
}

2)Trigger on Contact to update the account when contact is inserted

trigger accountupdate on Contact (after insert) {
    List<Account> lstaccount=new List<Account>();
    for(Contact c:Trigger.new){
            if(c.accountid!=null){
                Account acc=new Account(id=c.accountid);
                acc.description='contact is created with name:'+c.lastname;
                lstaccount.add(acc);
            }
   
    }
//Here i am using boolean variable  called "recursive" to avoid reursive calling from trigger to another trigger
    if(lstaccount!=null && lstaccount.size()>0 && recursiveavoid.recursive==false){
            recursiveavoid.recursive=true;
            update lstaccount;                   
    }
 }

Thursday, 9 August 2012

Display Trigger names of selected objects

Hi,
I am trying to explain to show the trigger names for selected object from picklist on visualforce page.

For this i used Dynamic apex and Apextrigger object.

Controller:
------------
public  class Dynamicobjectstriggerspageclass {
    public boolean ren { get; set; }
    public List<apextrigger> Triggerss { get; set; }
    public List<SelectOption> items { get; set; }
    public String selectedObj { get; set; }
    Public List<SelectOption> trignames{get;set;}
    public string selectedtrigname{get;set;}
    public Dynamicobjectstriggerspageclass (){
        Triggerss=new List<apextrigger>();
        trignames=new List<selectoption>();
        List<Schema.sObjecttype> lst= Schema.getGlobalDescribe().values();
        items= new List<SelectOption>();
        items.add(new SelectOption('','--None--'));
        for(Schema.sobjecttype s:lst){
        //if(String.valueOf(s).contains('__c'))
            items.add(new SelectOption(string.valueOf(s),String.valueOf(s)));
        }
        items.sort();
    }  
    public void fun1(){
       
    }
    public List<selectoption> getapextriggers(){
    
        if(selectedObj!=null && selectedObj!=''){
               Triggerss=new List<apextrigger>();
               trignames=new List<selectoption>();     
        trignames.add(new SelectOption('','--None--'));
        for(ApexTrigger aptrig:[select id,name from apextrigger where TableEnumOrId=:selectedObj]){
             trignames.add(new SelectOption(aptrig.id,aptrig.name));
        }
        }
        return trignames;      
    }

}
--------------------------------------
Visualforce Page
---------------------------------------
<apex:page controller="Dynamicobjectstriggerspageclass">
<apex:form >
<apex:actionfunction name="fun" action="{!fun1}" rerender="trig"/>
  <apex:pageblock >
      <apex:outputText value="Object Name"/> &nbsp;
        <apex:SelectList value="{!selectedObj}" size="1" onchange="fun()">
          <apex:selectOptions value="{!items}"/>
           </apex:SelectList>
         <apex:outputpanel >
                <apex:outputText value="Trigger Name:"/>&nbsp;
                <apex:selectList value="{!selectedtrigname}" id="trig" multiselect="false" size="1">
                                <apex:selectoptions value="{!apextriggers}"/>
                </apex:selectList>
         </apex:outputpanel>
   </apex:pageblock>
  </apex:form>
</apex:page>

Wednesday, 1 August 2012

Retrieing all fields without specifying field names in SOQL Query

Hi,
I am trying to explain how to get all fields data from an sobject without specifying particular fields  in query(SOQL) in Apex.
Because we cannot use '*' symbol in SOQL query to retrieve all fields from an sobject as in oracle(sql) in Apex.For every field to query  in
sobject  we need to specify  field names.So in the case of selecting all fields we need to write all fields in SOQL ,to avoid this
the  dynamic SOQL preparation with all fields using dynamic apex snippet is helpful.
Here just we need to prepare a string with all fields using dynamic apex with comma separation and we  insert this in 'SOQL' query.


Map<String, Schema.SObjectField> M = Schema.SObjectType.Account.fields.getMap();
public List<sObject> lstaccount{get;set;}
 Public List<string> fieldlst{get;set;}
Public List<Schema.SobjectField> lstfields{get;set;}

string fieldnames=' ';
            fieldlst=new List<String>();
            fieldnamestoquery=new List<String>();
            for(Schema.SObjectField s:m.values()){
                    Schema.DescribeFieldResult sfield=s.getDescribe();
                    fieldnames+=s+',';  //Here we concatenating all field names with comma seperation for preparing SOQL query
                    lstfields.add(s);
                   fieldlst.add(string.valueof(sfield.getName()));//Field list contains apinames all fields of Account
            }
           
            fieldnames=fieldnames.substring(0,fieldnames.length()-1);//Fieldnames string contains all the fields with comma separation

            string query='select '+fieldnames+' from Account';//Here we are preparing string query(dynamic SOQL using "fieldnames" string)
            if(query!=null && query!='')
                    lstaccount=database.query(query);//Here we will get all field values from account.

Passing values of parameters to customcomponent from visualforce page

I am explaining here how to pass values from visualforce page to custom component.
To pass values from visualforce page we should have <apex:attribute> tag with name,type,assignto and description properties.
Now i am writing custom componet.
To write custom component we need to go setup->Appsetup->Develop->components
Apex components  starts with <apex:component> and ends with </apex:component>
eg:
==
<apex:component controller="controllerforcomponent">
    <apex:attribute name="sobjectname" type="string" assignTo="{!objectname}" required="true" description="for objectname storing"/>
    <apex:pageBlock >
        <apex:pageBlockTable value="{!records}" var="a">
            <apex:column value="{!a.id}"/>   
            <apex:column value="{!a['firstname']}"/>           
        </apex:pageBlockTable>   
    </apex:pageBlock>
</apex:component>
==========================================================================
controller
===========
public  class controllerforcomponent {
     public String objectname{get;set;}
     public LIst<sobject> lstData{get;set;}
     public String sQuery;
     public List<Sobject> getrecords(){
         sQuery ='';
         sQuery = sQuery + 'select id,firstname,lastname from ' + objectname;
         system.debug('squery:'+squery);
         lstdata = new LIst<Sobject>();
         lstdata = database.query(sQuery);
         if(lstData.size() != null && lstdata.size()>0)
             return lstdata;
         else
             return null;
     }
       
}
==========================================================================

=Here"name" property is useful for pass values to component from visualforce page.When we set the  value to "name" property value called sobjectname as shown below.

<apex:page sidebar="false" >
    <c:Mycustomcomponent sobjectname="user"/>
</apex:page>

 this "user" will pass to customcomponent through sobjectname and assignto string property  called " objectname"  through <apex:attribute> tag in  our controller called "controllerforcomponent".
Our business logic is writing in controller.


output for page with customcomponent:
===============================