+ Start a Discussion
Sangeetha TSangeetha T 

Make my trigger work for existing records in salesforce

Hi friends I have created a trigger in salesforce to find the number of contacts associated with an account 

The trigger is not firing for the existing records ...Is der any way to sort this if so ...How 

Thanks in advance 
Trigger ContactCountTrigger on Contact(After insert,After Delete,After Undelete)
{
  Set<Id> setAccountIds = new Set<Id>();
  
  //Whenever your working with After Undelete operation you can access data through 
  //Trigger.new or Trigger.newMap but not with Trigger.old or Trigger.oldmap variables
  if(Trigger.isInsert || Trigger.isUndelete)
  {
   for(Contact con : Trigger.new)
   {
    setAccountIds.add(con.AccountId);
   }
  }
  
  if(Trigger.isDelete)
  {
   //if you use Trigger.new below in place of Trigger.old you will end up with 
   //System.NullPointerException:Attempt to de-reference a null object
   for(Contact con : Trigger.old) 
   {
    setAccountIds.add(con.AccountId);
   }
  }
  
 List<Account> listAccs = [Select id,name,Number__c,(Select id from contacts) from Account where Id in : setAccountIds];
  for(Account acc :listAccs)
  {
   acc.Number__c= acc.contacts.size();
  }
  update listAccs;
}
}

 
Amit Chaudhary 8Amit Chaudhary 8
Triggere only only execute for those record which are updated by UI or data loader. IF you want to update existing record then you can create the batch job for old record.
http://amitsalesforce.blogspot.in/2016/02/batch-apex-in-salesforce-test-class-for.html

Batch Apex
A Batch class allows you to define a single job that can be broken up into manageable chunks that will be processed separately.

When to use Batch Apex
One example is if you need to make a field update to every Account in your organization. If you have 10,001 Account records in your org, this is impossible without some way of breaking it up. So in the start() method, you define the query you're going to use in this batch context: 'select Id from Account'. Then the execute() method runs, but only receives a relatively short list of records (default 200). Within the execute(), everything runs in its own transactional context, which means almost all of the governor limits only apply to that block. Thus each time execute() is run, you are allowed 150 queries and 50,000 DML rows and so on. When that execute() is complete, a new one is instantiated with the next group of 200 Accounts, with a brand new set of governor limits. Finally the finish() method wraps up any loose ends as necessary, like sending a status email.

Sample Batch Apex
1) Start method
is automatically called at the beginning of the apex job. This method will collect record or objects on which the operation should be performed. These record are divided into subtasks & passes those to execute method.

2) Execute Method performs operation which we want to perform on the records fetched from start method.

3) Finish method executes after all batches are processed. Use this method to send confirmation email notifications.

NOTE:- Add your Trigger logic in Batch job for old record
global class AccountUpdateBatchJob implements Database.Batchable<sObject> 
{
    global Database.QueryLocator start(Database.BatchableContext BC) 
    {
        String query = 'Select id,name,Number__c from Account';
        
        return Database.getQueryLocator(query);
    }
    global void execute(Database.BatchableContext BC, List<Account> scope) 
    {
		Set<Id> setAccountIds = new Set<Id>();
        for(Account a : scope)
        {
			setAccountIds.add(a.id);
        }
		
		List<Account> listAccs = [Select id,name,Number__c,(Select id from contacts) from Account where Id in : setAccountIds];
		for(Account acc :listAccs)
		{
			acc.Number__c= acc.contacts.size();
		}
		
        update listAccs;
    }
    global void finish(Database.BatchableContext BC) {
    }
}


Let us know if this will help you