function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Nathan Prats 22Nathan Prats 22 

Avoid “Apex CPU time limit exceeded” - Trying to use a map

Hi, 

I have this code that doesn't work. I'm trying to convert it as a map as I read in the best practices that I should use maps. 
The custom field Contact_Owner_Account_Owner__c  returns TRUE when the ownerId is different from the account ownerId. 
List<Contact> ContList = [SELECT Id,OwnerId,Account.OwnerId,Contact_Owner_Account_Owner__c 

             FROM Contact 

             WHERE Contact_Owner_Account_Owner__c = TRUE

             AND AccountId != ''];



for(Contact Cont : ContList){   

  Cont.OwnerId = Cont.Account.OwnerId ;

}



update ContList;
Thanks for your help, 

Nathan
 
Best Answer chosen by Nathan Prats 22
Nathan Prats 22Nathan Prats 22
Actually I reached the heap size limit because I put a DML operation outside a for loop 
Correct code is this, with the DML in the middle
 
For(List<Contact> ContList = [
    SELECT Id,OwnerId,Account.OwnerId,Contact_Owner_Account_Owner__c 
    FROM Contact 
    WHERE Contact_Owner_Account_Owner__c = TRUE
    AND AccountId != '']);{
        
        for(Contact Cont : ContList){   
            Cont.OwnerId = Cont.Account.OwnerId ;
        }
        
        update ContList; 
    }

 

All Answers

Nathan Prats 22Nathan Prats 22
No I mean this code doesn't work when I have 5000 thousand records to reassign to the right owner. My understanding from the salesforce developer documentation is that I should write a Map instead. 

I tried this code in the execute anonymous window but I'll use it as a Scheduled Apex in order to reassign contacts to the account owner each morning at 8AM for example. It's supposed to maintain our data quality. 
mritzimritzi
If all you need is to copy OwnerID from Account into Contact, you can use Workflow. No Code required. That's what Salesforce recommends as well (using as much as Configuration as possible, and coding when configurations can't serve the purpose)

Create a Workflow on Contact, set criteria to 'created and every time it's edited'
Use formula
OR(
    ISNEW(),
    ISCHANGED(Account.OwnerId)
)

Immediate Action:
Field Update
OwnerId = Account.OnwerId

Activate Workflow. Done.

Mark this as Best Answer, if this solves your problem.​
Nathan Prats 22Nathan Prats 22
Actually I reached the heap size limit because I put a DML operation outside a for loop 
Correct code is this, with the DML in the middle
 
For(List<Contact> ContList = [
    SELECT Id,OwnerId,Account.OwnerId,Contact_Owner_Account_Owner__c 
    FROM Contact 
    WHERE Contact_Owner_Account_Owner__c = TRUE
    AND AccountId != '']);{
        
        for(Contact Cont : ContList){   
            Cont.OwnerId = Cont.Account.OwnerId ;
        }
        
        update ContList; 
    }

 
This was selected as the best answer