0

I have a list to to accumulate All dB Errors, I need to use that list in finish. But the transient variable is null in finish. Here is My class:


global class BatchToDoSomething implements Database.Batchable<sObject>,Database.stateful{
    //other variables
    global transient List<Database.Error> dbErrors = new List<Database.Error>();
    global List<Log__c> logs = new List<Log__c>();
    global BatchToDoSomething (Set<Id> ProjIds,STring pbName){
        System.debug('transient in construnctor '+dbErrors);
        System.debug('transient in construnctor logs '+logs);
        //varaible inits;
    }
    
    global Database.QueryLocator start(Database.BatchableContext BC){
        System.debug('transient in start '+dbErrors);
        System.debug('transient in start logs '+logs);
        String query = 'some query';
        System.debug('query'+query);
        return Database.getQueryLocator(query);
    }
    
    global void execute(Database.BatchableContext BC,List<Finance__c> scope){
        try{
            System.debug('transient in execution '+dbErrors);
            System.debug('transient in execution logs '+logs);

        }
        catch(Exception e){
           //some catch
        }
        
    }
    global void finish(Database.BatchableContext BC){
        System.debug('transient in finish '+dbErrors);
        System.debug('transient in finsih logs '+logs);
        if (dbErrors!=null && dbErrors.size()>0) {
            LogUtility.creatLogsFromDatabaseErrors('someclass', BC.getJobId(), 'W__c', dbErrors);
        }
        if(logs!=null && logs.size()>0){
            LogUtility.insertLogs(logs);
        }
    }
}

The logs are as follows : [![enter image description here][1]][1] Some names are hidden/changed due to confidentiality. You can not that dbErrors get null after sometime but logs is maintained. Note :

  1. dbErrors need to be transient because without it, Serialization error is there [1]: https://i.stack.imgur.com/MebKq.png
4
  • 1
    Why have you even declared it transient, remove that. Your Database.stateful{ will make sure your state is maintained till finish is called. Dec 9, 2021 at 11:47
  • 2
    Hello and welcome to SFSE (Salesforce StackExchange). I think you have to go back to design this because transient is making the variable not persistent between executions (even with you marking the job as stateful. You may want rethink what you want to store in the log or when, because Database.Error are not serializable. Dec 9, 2021 at 11:54
  • @NagendraSingh Database.Error is not Serializable hence an exception is through, since we are implementing Stateful
    – AmanSharma
    Dec 9, 2021 at 12:15
  • But why do you need to pass that to finish, insert that in the same execute method. Dec 9, 2021 at 12:24

1 Answer 1

2

Transient variables are not serialized, and serializing some types of objects throws exceptions because they are not serializable. You'll need to convert the Database.Error objects into something you can serialize (e.g. a class that you write).

class DatabaseError {
  String message;
  // etc...
}
DatabaseError[] errors = new DatabaseError[0];
// ...
public void execute(Database.BatchableContext context, Finance__c[] scope) {
  try {
    // ...
  } catch(Exception e) {
    errors.add(convertToError(e));
  }
}
1
  • Yeah, did that only. Thankx for answer
    – AmanSharma
    Dec 10, 2021 at 5:04

You must log in to answer this question.

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