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
Pavan_NMPavan_NM 

Change ownership of records using batch apex

Hi Experts,

I have requirment 
1. I need to fetch all the inactive users (IsActive==False),
2. if the inactive users having ownership for records on object Acocunt, Contact,Opportunity, we have to change record ownership to its imidiate manager assigned to that users.
3. for this we required batch class and sechudular which runs daily basis, covering all 3 objects iterative maner so no Apex cpu limit error occure

Kindly help me out.

 

 

CharuDuttCharuDutt
Hii Pavan
Try Below Code
Batch Class
public class AccountOwnerUpdate implements Database.Batchable<sObject> {
    public Database.QueryLocator start(Database.BatchableContext bc) {
        return Database.getQueryLocator('SELECT id,ManagerId FROM User Where IsActive = false And ManagerId != null');
    }
    public void execute(Database.BatchableContext bc, List<User> records){
        Map<Id,Id>InactiveUserIdmap = new map<id,id>();
        
        for(User u : records){
           InactiveUserIdmap.put(u.Id,u.ManagerId);
        }
        list<Account> lstAccount = [Select Id,OwnerId From Account Where OwnerId In :InactiveUserIdmap.keySet()];
        list<Contact> lstContact = [Select Id,OwnerId From Contact Where OwnerId In :InactiveUserIdmap.keySet()];
        list<Opportunity> lstOpportunity = [Select Id,OwnerId From OpportunityWhere OwnerId In :InactiveUserIdmap.keySet()];
        for(Account Acc : lstAccount){
            if(InactiveUserIdmap.containsKey(Acc.OwnerId)){
                Acc.OwnerId = InactiveUserIdmap.get(Acc.OwnerId);
            }
        }
        for(Contact Con : lstContact ){ 
            if(InactiveUserIdmap.containsKey(Con.OwnerId)){ 
                Con.OwnerId = InactiveUserIdmap.get(Con.OwnerId); 
            } 
        }
        for(Opportunity opp : lstOpportunity ){
            if(InactiveUserIdmap.containsKey(opp.OwnerId)){
                opp.OwnerId = InactiveUserIdmap.get(opp.OwnerId);
             }
        }
        if(lstAccount.size()>0){
            update lstAccount;
        }
        if(lstContact .size()>0){ 
            update lstContact ; 
        }
        if(lstOpportunity .size()>0){ 
            update lstOpportunity ; 
        }
    }
    public void finish(Database.BatchableContext bc){
        Id job = bc.getJobId();
    }
}

Scheduler Class
global class DailyAccountProcessor implements Schedulable {
    
    global void execute(SchedulableContext ctx) {
       AccountOwnerUpdate lp = new AccountOwnerUpdate ();
        Id batchId = Database.executeBatch(lp);
    }
}
Please Mark It As Best Answer If It Helps
Thank You!
Jennifer samiJennifer sami
There are cases where it is necessary to change the ownership of records. For example, when importing customer data, you might want to update their ownership information so that they now belong to another account. The following tutorial outlines how this can be done using the Batch Apex feature in Salesforce load more (https://shepskymix.com/akita-german-shepherd-husky-mix/)
ravi soniravi soni
Hi Pavan,
try below code but before apply it make sure your user  managerId is not empty otherwise you can get error.
public class updateOwnerShipOfSobjects implements Database.Batchable<sObject> {
    public Database.QueryLocator start(Database.BatchableContext bc) {
        return Database.getQueryLocator('SELECT id,ManagerId FROM User Where IsActive = false');
    }
    public void execute(Database.BatchableContext bc, List<User> records){
        Map<Id,Id>inactiveUserWithManagerMap = new map<Id,Id>();
        list<sObject> lstSobjects = new list<sObject>();
          system.debug('records ===> ' + records);
        for(User u : records){
           inactiveUserWithManagerMap.put(u.Id,u.ManagerId);
        }
        system.debug('inactiveUserWithManagerMap ===> ' + inactiveUserWithManagerMap);
        list<Account> lstAccount = [Select Id,OwnerId From Account Where OwnerId In :inactiveUserWithManagerMap.keySet()];
        list<Contact> lstContact = [Select Id,OwnerId From Contact Where OwnerId In :inactiveUserWithManagerMap.keySet()];
        list<Opportunity> lstOpportunity = [Select Id,OwnerId From Opportunity Where OwnerId In :inactiveUserWithManagerMap.keySet()];
         for(Account Acc : lstAccount){
            if(inactiveUserWithManagerMap.containsKey(Acc.OwnerId)){
                Acc.OwnerId = inactiveUserWithManagerMap.get(Acc.OwnerId);
                lstSobjects.add(Acc);
            }
            
        }
        for(Contact Con : lstContact){
            if(inactiveUserWithManagerMap.containsKey(Con.OwnerId)){
                Con.OwnerId = inactiveUserWithManagerMap.get(Con.OwnerId);
                lstSobjects.add(Con);
            }
        }
         for(Opportunity Opp : lstOpportunity){
            if(inactiveUserWithManagerMap.containsKey(Opp.OwnerId)){
                Opp.OwnerId = inactiveUserWithManagerMap.get(Opp.OwnerId);
                 lstSobjects.add(Opp);
            }
        }
        
        if(lstSobjects.size()>0){
            update lstSobjects;
        }
        system.debug('lstSobjects====> ' + lstSobjects);
    }
    
    public void finish(Database.BatchableContext bc){
        Id job = bc.getJobId();
    }
}
Scheduler Class
global class DailyAccountProcessor implements Schedulable {
    
    global void execute(SchedulableContext ctx) {
       updateOwnerShipOfSobjects lp = new updateOwnerShipOfSobjects();
        Id batchId = Database.executeBatch(lp);
    }
}

don't forget to mark it as best answer.
thank you
 
Pavan_NMPavan_NM

Thanks for reply,

for one or more users I have more than 50k records using all objects in batch,
can we make this batch Iterable to make it work for more than 50k records?

this batch giving error -- Too many query rows: 50001
is it possible to avoide this error?

Thanks for support,