Apologies in advance as my understanding of Apex is pretty bad... I'm attempting to create a trigger that updates the owners of all Contacts within an Account when a custom user lookup field on the Account is changed. Below is what I've got, but I'm definitely not storing the variables properly...

trigger pipelineRepContactUpdate on Account (after update) {

    List<Contact>ContactList        = new List<Contact>();
    List<Contact>UpdatedContactList = new List<Contact>();
    List<Contact>FinalContactList   = new List<Contact>();

    for(Integer index = 0, size = Trigger.new.size(); index < size; index++) {
      if(Trigger.isInsert || (Trigger.old[index].Pipeline_Rep__c != Trigger.new[index].Pipeline_Rep__c && Trigger.new[index].Pipeline_Rep__c != NULL)) {
        // New record or pipeline rep changed ...
        String pr;
        pr              = [SELECT Pipeline_Rep__c FROM Account WHERE Id IN :Trigger.new LIMIT 1];
        ContactList     = [SELECT id, OwnerId, AccountId FROM Contact WHERE AccountId IN :Trigger.new];

    For(Contact c:UpdatedContactList){
        c.OwnerId = pr.Pipeline_Rep__c;

    Update FinalContactList;


Any help would be appreciated -- thanks!

  • 2
    DML inside for loop no never!!! May 2, 2017 at 5:56
  • 1
    You should move if(Trigger.isInsert this condition outside the for loop, do add this check in the very beginning; May 2, 2017 at 5:57

2 Answers 2


in spite of checking the old value by iterating the loop you can check this by using Trigger.oldMap and Trigger.newMap, use the below snippet :

trigger pipelineRepContactUpdate on Account (after update) {
    Set<Id> lst_acc_id = new Set<Id>();//Store the sets of Impacted Account for which you have changed the field value
    Map<Id,Id> map_accounId_OwnerId = new Map<Id,Id>();//map of account Id and OwnerId
    List<Contact> lst_updated_contact = new List<Contact>();//List of updated contact

    if(Trigger.isAfter && Trigger.isUpdate){ 
        for(Account  acc : Trigger.New){ 
            //Checks whether the value changes from previous one or not
            if((Trigger.oldMap.get(acc.Id).Pipeline_Rep__c != Trigger.newMap.get(acc.Id).Pipeline_Rep__c) &&  Trigger.newMap.get(acc.Id).Pipeline_Rep__c!=null){
                map_accounId_OwnerId.put(acc.Id,acc.Pipeline_Rep__c);//preparing the map

        //query all the contact related to the Account
        List<Contact> lst_con = [Select Id,OwnerId,AccountId from Contact where AccountId IN : lst_acc_id];   
            for(Contact con : lst_con){
                con.OwnerId = map_accounId_OwnerId.get(con.AccountId);// assigning the Account Pipeline_Rep__c field


        update  lst_updated_contact;//update the contact records


it should work.


Never run SOQL queries in for loop - Take a look at Apex best practices

This is my understanding of you question/requirement:

trigger pipelineRepContactUpdate on Account (after update) {

    List<Contact> contactList = new List<Contact>();
    Map<Id, Account> oldAccounts = Trigger.oldMap;
    Map<Id, Account> newAccounts = Trigger.newMap;
    Map<Id, String> accountToOwner = new Map<Id, String>();

    for(Account account : newAccounts.values()) {
      (oldAccounts.get(account.Id).Pipeline_Rep__c != account.Pipeline_Rep__c && account.Pipeline_Rep__c != NULL) {
        // New record or pipeline rep changed ...
        accountToOwner.put(account.Id, account.Pipeline_Rep__c);
    contactList     = [SELECT id, OwnerId, AccountId FROM Contact WHERE AccountId IN :accountToOwner.keySet()];
    For(Contact c : contactList){
        if (accountToOwner.containsKey(c.AccountId)) {
            c.OwnerId = accountToOwner.get(c.AccountId);
    update contactList;


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .