BETTERMassUpdateContactsOnAccount.apex

Image:cookbook.jpg

Force.com Cookbook Sample Code
Chapter 4: Best Practices for Writing Apex - Avoiding Apex Governor Limits

To download all the code samples, access the Cookbook. - Image:Key_icon.gif

This Apex trigger is part of an example that demonstrates several methods for avoiding execution governor limits, including:

  • Making sure that database statements such as insert(), update(), and delete() operate in bulk
  • Using Limits.getDMLRows() for error handling
  • Limiting queries by using static class variables to store query results
  • Testing bulk behavior
trigger BETTERMassUpdateContactsOnAccount on Account (after update) {

	//The map allows us to keep track of the accounts
	//that actually have new addresses

	Map<Id, Account> accountsWithNewAddresses = new Map<Id, Account>();

	//Trigger.new is an array of Accounts containing the updated
	//value. This loop iterates over the list, and adds any that
	//have new addresses to the accountsWithNewAddresses Map

	for (Integer i = 0; i < Trigger.new.size(); i++) {

		if ( (Trigger.old[i].ShippingCity != Trigger.new[i].ShippingCity)

			 || (Trigger.old[i].ShippingCountry != Trigger.new[i].ShippingCountry)
			 || (Trigger.old[i].ShippingPostalCode != Trigger.new[i].ShippingPostalCode)
			 || (Trigger.old[i].ShippingState != Trigger.new[i].ShippingState)
			 || (Trigger.old[i].ShippingStreet != Trigger.new[i].ShippingStreet)) {

			accountsWithNewAddresses.put(Trigger.old[i].id, Trigger.new[i]);
		}
	}

	List<Contact> updatedContacts = new List<Contact>();

	//Here we can see two syntatic features of Apex:
	// 1) iterating over an embedded SOQL query
	// 2) binding an array directly to a SOQL query with 'in'

	for (Contact c : [select id, accountId, MailingCity, MailingCountry, MailingPostalCode, MailingState, MailingStreet 

	                  from contact where accountId in :accountsWithNewAddresses.keySet()]) {

		Account parentAccount = accountsWithNewAddresses.get(c.accountId);

		c.MailingCity = parentAccount.ShippingCity;
		c.MailingCountry = parentAccount.ShippingCountry;
		c.MailingPostalCode = parentAccount.ShippingPostalCode;
		c.MailingState = parentAccount.ShippingState;
		c.MailingStreet = parentAccount.ShippingStreet;

		//Rather than insert the contacts individually, add the
		//contacts to an array and bulk insert the array.
		//This makes the trigger run faster and allows us to
		//avoid hitting the governor limit on DML statements

		updatedContacts.add(c);
	}

	update updatedContacts;
}

Sample code provided by salesforce.com. All rights reserved.