I'm having this dilemma regarding the result for Database.Upsert(List, boolean).

Database.Upsert returns Database.UpsertResult and it provides as the Id of the record that was successfully inserted/updated.

However, if an ERROR happens during Insert, when you try to get the Id in UpsertResult via getId() function, you will see that the Id is NULL.

Now I understand this part because the record does not yet exist in DB but I need to return the UpsertResult to another method that needs to know which record failed.


List<Asset> finalAssetList = new List<Asset>();
    //Loop exists here that fills up finalAssetList

    List<Database.UpsertResult> upsertAssetResult = Database.upsert(finalAssetList, false);
    List<ResultMessage> rmList = new List<ResultMessage>();
    for(Database.UpsertResult ur : upsertAssetResult) {
        ResultMessage rm = new ResultMessage();
        rm.error_message = ur.getErrors();
        rm.recordId = ur.getId();

    return rmList;

Please take note that ResultMessage is an inner class whose variables are recordId and error_message.

If an Error happens during Insert, my rmList will contain a record with NULL in its recordId.

Is there any way that I can circumvent this?


  • I am marking as duplicate, as the you can find the same approach from the above answer. – Santanu Boral May 16 '18 at 3:48

UpsertResult Class has isSuccess() method with which you'd know if the DML operation was Successful.

We easily check we can lookup to SObject list while iterating over Database.UpsertResult List, this is due to fact that index of records are retained in result. Also mentioned in documentation:

An array of Database.UpsertResult objects is returned with the upsert database method. Each element in the UpsertResult array corresponds to the sObject array passed as the sObject[] parameter in the upsert Database method; that is, the first element in the UpsertResult array matches the first element passed in the sObject array, the second element corresponds with the second element, and so on. If only one sObject is passed in, the UpsertResults array contains a single element.

Some code to verify this-

Savepoint sp = Database.setSavepoint();
List<Account> lstAccount = new List<Account>{
    new Account(Name = 'Test 1'),
    new Account(Name = ''),
    new Account(Name = 'Test 2')
List<Database.UpsertResult> upsertAssetResult = Database.upsert(lstAccount, false);

for(Integer index = 0; index < upsertAssetResult.size(); index++) {
    if(upsertAssetResult[index].isSuccess()) {
        System.debug('Record was created-' + lstAccount[index]);
    } else {
        // collect failed records here
        System.debug('Record failed-' + lstAccount[index]);


Produces this output:

Record was created-Account:{Name=Test 1, Id=0010I00001qPGwzQAG}

Record failed-Account:{Name=}

Record was created-Account:{Name=Test 2, Id=0010I00001qPGx0QAG}

| improve this answer | |

Not the answer you're looking for? Browse other questions tagged or ask your own question.