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
Nitin sharma 425Nitin sharma 425 

An exception while Updating Accounts through batch Apex

Hi All,

Exception:-
First error: Row with null Id at index: 0

I am getting an exception while showing the total number of  contacts on the account using batch Apex.Not able to resolve, can somebody help?

public class UpdateAccountwithBatchApex implements Database.Batchable<sObject>,Database.Stateful
{
    
    Public Integer RecordsProcessed=0;
    public Database.QueryLocator Start(DataBase.BatchableContext context)
    {
        return Database.getQueryLocator([Select id from account]);
    }
Public void Execute(Database.batchableContext context,list<Account>scope)
{
Map<Id, AggregateResult> results = new Map<Id, AggregateResult>([SELECT Accountid Ids, COUNT(Id) amt FROM contact WHERE Accountid = :scope GROUP BY Accountid]);
        list<Account>accrec=new list<account>();
         Account acc=new Account();
        for(Account record: scope)
        {
            System.debug('I am in for loop');
            AggregateResult amount = results.get(record.Id);
            if(amount != null)
            {
              System.debug('I am in the if statement');
              
              accrec.add(new Account(Id=(Id)amount.get('ids'),Total_no_of_Contacts__c=(Decimal)amount.get('amt')));  
                
                                 
             }
            else
            {
                
            accrec.add(new Account(Id=(Id)amount.get('ids'),Total_no_of_Contacts__c=null));  
                          
                
            }
}
update accrec ;
 }
        

    public void Finish(Database.BatchableContext de)
    {
 
        
      System.debug('Records processed were'+RecordsProcessed);  
        
        
    }
 
       
 }

Thanks,
 
Omar Rajab 94Omar Rajab 94
Hi Nitin,

The Syntax of the soql query is not correct. It should be like this:
Map<Id, AggregateResult> results = new Map<Id, AggregateResult>([SELECT Accountid Ids, COUNT(Id) amt FROM contact WHERE Accountid IN :scope GROUP BY Accountid]);

Because "scope" is a list, so you have to use The IN Opertor in the soql! 

regards
Omar
Nitin sharma 425Nitin sharma 425
Thanks for your reply.I have tried with the In operator and it is still giving me the same error Apex script unhandled exception by user/organization: 0055Y00000Fe5x5/00D5Y000002UQeD Failed to process batch for class 'great' for job id '7075Y000086GHRJ' caused by: System.ListException: Row with null Id at index: 0 Class.great.Execute: line 11, column 1 Thanks ,Once again
ravi soniravi soni
hi Nitin,
try following betch class.
public class UpdateAccountwithBatchApex implements Database.Batchable<sObject>,Database.Stateful
{
    
    Public Integer RecordsProcessed=0;
    public Database.QueryLocator Start(DataBase.BatchableContext context)
    {
        return Database.getQueryLocator([Select id from account]);
    }
Public void Execute(Database.batchableContext context,list<Account>scope)
{
Map<Id, AggregateResult> results = new Map<Id, AggregateResult>([SELECT Accountid Ids, COUNT(Id) amt FROM contact WHERE Accountid = :scope GROUP BY Accountid]);
        list<Account>accrec=new list<account>();
         Account acc=new Account();
        for(Account record: scope)
        {
            System.debug('I am in for loop');
            AggregateResult amount = results.get(record.Id);
            if(amount != null)
            {
              System.debug('I am in the if statement');
              
              accrec.add(new Account(Id=(Id)amount.get('ids'),Total_no_of_Contacts__c=(Decimal)amount.get('amt')));  
                
                                 
             }
            else
            {
                
            accrec.add(new Account(Id=(Id)amount.get('ids'),Total_no_of_Contacts__c=null));  
                          
                
            }
}
update accrec ;
 }
        

    public void Finish(Database.BatchableContext de)
    {
 
        
      System.debug('Records processed were'+RecordsProcessed);  
        
        
    }
 
       
 }
let me know if it helps you and marking it as best.
Thank You
 
Omar Rajab 94Omar Rajab 94
some contacts does not have an account, so the account  id = null.
amount.get('ids') = null
So the list "accrec" have account records with Id = null, which throws the Exception during the update. Form more understanding make system debug for this SOQL: 
SELECT Accountid Ids, COUNT(Id) amt FROM contact WHERE Accountid IN :scope GROUP BY Accountid
Anyway try the code below: 
public class UpdateAccountwithBatchApex implements Database.Batchable<sObject>, Database.Stateful

{



	Public Integer RecordsProcessed = 0;

	public Database.QueryLocator Start(DataBase.BatchableContext context)

	{

		return Database.getQueryLocator([Select id from account]);

	}

	Public void Execute(Database.batchableContext context, list<Account> scope)

	{

		Map<Id, AggregateResult> results = new Map<Id, AggregateResult> ([SELECT Accountid Ids, COUNT(Id) amt FROM contact WHERE Accountid IN :scope GROUP BY Accountid]);

		list<Account> accrec = new list<account> ();

		Account acc = new Account();

		for (Account record : scope)

		{

			System.debug('I am in for loop');

			if (results.containsKey(record.Id)) {

				AggregateResult amount = results.get(record.Id);

				if (amount != null)

				{

					System.debug('I am in the if statement');

					if (amount.get('ids') != null) {

						accrec.add(new Account(Id = (Id) amount.get('ids'), Total_no_of_Contacts__c = (Decimal) amount.get('amt')));

					}



				}

				else

				{

					if (amount.get('ids') != null) {

						accrec.add(new Account(Id = (Id) amount.get('ids'), Total_no_of_Contacts__c = null));

					}



				}

			}

		}



		if (!accrec.isEmpty()) {



			update accrec;

		}

	}





	public void Finish(Database.BatchableContext de)

	{





		System.debug('Records processed were' + RecordsProcessed);





	}





}

Please mark it as the best answer if it helps you to fix the issue.

Regards,
Omar
Nitin sharma 425Nitin sharma 425
Hi Veer,

I still have the same problem.Please look at the debug logs and there are few recoords as per debug logs but none have null in it.As per debug logs,All records have Id's and count of contacts.



SOQL_EXECUTE_BEGIN|[13]|Aggregations:0|SELECT Accountid Ids, COUNT(Id) amt FROM contact WHERE Accountid IN :tmpVar1 GROUP BY Accountid
12:48:03.0 (6630357)|SOQL_EXECUTE_END|[13]|Rows:6
12:48:03.0 (6664798)|HEAP_ALLOCATE|[13]|Bytes:28
12:48:03.0 (6710378)|HEAP_ALLOCATE|[13]|Bytes:246
12:48:03.0 (6748562)|HEAP_ALLOCATE|[13]|Bytes:28
12:48:03.0 (6820068)|HEAP_ALLOCATE|[13]|Bytes:301
12:48:03.0 (6839042)|HEAP_ALLOCATE|[13]|Bytes:327
12:48:03.0 (6860539)|USER_DEBUG|[13]|DEBUG|The records are as follows(AggregateResult:{Ids=0015Y00002iWAvRQAW, amt=250}, AggregateResult:{Ids=0015Y00002iWQY0QAO, amt=229}, AggregateResult:{Ids=0015Y00002iWTnAQAW, amt=3}, AggregateResult:{Ids=0015Y00002iWrxfQAC, amt=1}, AggregateResult:{Ids=0015Y00002iWtgUQAS, amt=1062}, AggregateResult:{Ids=0015Y00002iWtkUQAS, amt=4})
12:48:03.0 (6889201)|STATEMENT_EXECUTE|[15]
12:48:03.0 (6905745)|HEAP_ALLOCATE|[15]|Bytes:4
12:48:03.0 (6916996)|HEAP_ALLOCATE|[15]|Bytes:4
12:48:03.0 (7410992)|SOQL_EXECUTE_BEGIN|[15]|Aggregations:0|SELECT Accountid Ids, COUNT(Id) amt FROM contact WHERE Accountid IN :tmpVar1 GROUP BY Accountid
12:48:03.0 (11778609)|SOQL_EXECUTE_END|[15]|Rows:6
12:48:03.0 (11807325)|HEAP_ALLOCATE|[15]|Bytes:28
12:48:03.0 (11848039)|HEAP_ALLOCATE|[15]|Bytes:246
12:48:03.0 (11896776)|HEAP_ALLOCATE|[15]|Bytes:28
12:48:03.0 (11946428)|HEAP_ALLOCATE|[15]|Bytes:12
12:48:03.0 (12087551)|HEAP_ALLOCATE|[15]|Bytes:32
12:48:03.0 (12155777)|FATAL_ERROR|System.ListException: Row with null Id at index: 0




 
Nitin sharma 425Nitin sharma 425
HI Omar,

Thanks for your explanation Problem still persists.

Map<Id, AggregateResult> results = new Map<Id, AggregateResult> ([SELECT Accountid Ids, COUNT(Id) amt FROM contact WHERE Accountid IN :scope GROUP BY Accountid]);

When we look at the above line.Are we not only collecting Accounts with contacts ? .

Start() method will collect all the Accounts and pass it to the Execute method.Execute method will only work on the contacts which have accounts with them then how come the question of accounts with no contacts arises....I may be missing something here.

Even debug logs are only showing Acoounts with Id's and Total of Contacts with them....It is not showing anything related to null etc.

I guess the line below will will only pick up accounts with contact only because of the filter....Am i missing something here?

Map<Id, AggregateResult> results = new Map<Id, AggregateResult> ([SELECT Accountid Ids, COUNT(Id) amt FROM contact WHERE Accountid IN :scope GROUP BY Accountid]); 


Thanks
 
Nitin sharma 425Nitin sharma 425
Hi Veer and Omar,

I have made some changes and it is working.Howeer,would like to hear from you guys if the below given code will be sufficient in all situations as I do not want it to break and throw Exceptions.Please guide or advise.

Question:-Do i need yo worry about Accounts without contacts?.

As per me,below given line will ignore all Accounts which does not have any contacts with them?Am I right ?.
Please let me know if anything else has to aded to the code.

Not sure if I have to worry about null Id's any more. 

SELECT Accountid Ids, COUNT(Id) amt FROM contact WHERE Accountid IN :scope GROUP BY Accountid]

Public class UpdateAccountwithBatchApex implements Database.Batchable<sObject>, Database.Stateful
{

Public Integer RecordsProcessed = 0;
public Database.QueryLocator Start(DataBase.BatchableContext context)

    {

        return Database.getQueryLocator([Select id from account]);

    }    
Public void Execute(Database.batchableContext context, list<Account> scope)
    {
        
        List<Account>ListOfAccRecords=new list<account>();
        System.debug('The records are as follows'+[SELECT Accountid Ids, COUNT(Id) amt FROM contact WHERE Accountid IN :scope GROUP BY Accountid]);
        AggregateResult[]agg=[SELECT Accountid Ids, COUNT(Id) amt FROM contact WHERE Accountid IN :scope GROUP BY Accountid];
        for(AggregateResult agr:agg)
          {
                       
          ListOfAccRecords.add(new Account(Id = (Id) agr.get('ids'),Total_number_Of_Contacts__c = (Decimal) agr.get('amt')));
    
          RecordsProcessed=RecordsProcessed+1;                                             
           }

        if (!ListOfAccRecords.isEmpty())
        {
            update ListOfAccRecords;

        }

    }

    public void Finish(Database.BatchableContext de)
    {
        System.debug('Records processed were' + RecordsProcessed);


    }
    

}



Thanks,
Nitin
 
Omar Rajab 94Omar Rajab 94
Hi Nitin,

Two points would be helpful for your code:
- you should use try/catch method
- you can use this query in the start method
SELECT Accountid Ids, COUNT(Id) amt FROM contact WHERE Accountid <> nullGROUP BY Accountid

in the excute method you replace list<Account> with
list<AggregateResult>


Please mark it as the best answer if it helps you to fix the issue.
Regards,
Omar