Database.SaveResult.getId() returns null

All we need is an easy explanation of the problem, so here it is.

I’m trying to update an account list and I need to get the Ids when the update fails.

I use the getId() method but for accounts which fail I get null.

It’s an update so my account already has an Id.

Is it normal ? If it is, how can I get the Ids list of non-updated accounts ?

Here is my code :

List<Account> accountsList = [select Id from Account];

for(Account a : accountsList) {
    a.Name = 'Test',
}

List<Database.SaveResult> res = Database.update(accountsList, false);

for (Database.SaveResult s : res) {
    if (!s.isSuccess()) {
        system.debug(s.getId()); // I get null here
     } 
}

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

You can match the updated records with the Database.SaveResults using a list iterator, which will give you access to the original record:

List<Account> accountsList = [select Id from Account];

for(Account a : accountsList) {
    a.Name = 'Test',
}

List<Database.SaveResult> res = Database.update(accountsList, false);

//for (Database.SaveResult s : res) { //replaced by the following line
for (Integer i = 0; i < accountsList.size(); i++) {
    Database.SaveResult s = res[i];
    Account origRecord = accountsList[i];
    if (!s.isSuccess()) {
        system.debug(s.getId()); // I get null here
        system.debug(origRecord.Id); //This should be the Id you're looking for
     } 
}

Method 2

See the SaveResult class docs: https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_database_saveresult.htm

and the example use:

// Iterate through each returned result
for (Database.SaveResult sr : srList) {
    if (sr.isSuccess()) {
        // Operation was successful, so get the ID of the record that was processed
        System.debug('Successfully inserted account. Account ID: ' + sr.getId());
    }
    else {
        // Operation failed, so get all errors                
        for(Database.Error err : sr.getErrors()) {
            System.debug('The following error has occurred.');                    
            System.debug(err.getStatusCode() + ': ' + err.getMessage());
            System.debug('Account fields that affected this error: ' + err.getFields());
        }
    }
}

The docs say that the getId() method only returns on success.

If this field contains a value, the object was successfully inserted
or updated. If this field is empty, the operation was not successful
for that object.

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply