7

We are updating our code to use the new accessLevel parameter in the update method of the Database class. We have cases where the object contains fields that cannot be edited (e.g. LastModifiedDate).

If we update the object using the normal update, the update works because we have not actually updated LastModifiedDate. However, if we use Database.update with AccessLevel.USER_MODE, we see the exception:

System.DmlException: Operation failed due to fields being inaccessible on Sobject Account, check errors on Exception or Result!

Sample code we have used is as below. The debug message prints: The field(s) "LastModifiedDate" are not accessible for update of Account

Account acc = new Account(name='Acc1');
insert acc;

acc = [select id, name, lastModifiedDate from Account where id = :acc.id];
acc.name = 'Acc1_updated';
update acc;

try {
    Database.update(acc, AccessLevel.USER_MODE);
} catch (DMLException dex) {
    System.debug('The field(s) "' + 
    String.join(dex.getDmlFieldNames(0), ', ') + '" are not accessible for update of Account');
    throw dex;
}

Similar issue with auto numbered name fields, formula fields, master-detail lookup fields etc.

Is there any way to use Database.update to update the object other than removing the field LastModifiedDate from the SOQL query select list? Any pointers will be appreciated.

1
  • Do you need to include the LastModifiedDate in the query? The code you have provided is not using it
    – fred
    Commented Nov 3, 2023 at 13:56

1 Answer 1

10

As you have seen, you cannot include LastModifiedDate when doing an update in user mode. The easiest way to fix this would be to create a new Account in Apex and use that to update. For example:

acc = [SELECT Id, Name, LastModifiedDate FROM Account WHERE Id = :accId];
Account accountToUpdate = new Account(Id = accId, Name = 'Acc1_updated');
update as user accountToUpdate;

An alternative way to do this would be to use the stripInaccessible method. For example:

List<Account> accList = [SELECT Id, Name, LastModifiedDate FROM Account WHERE Id = :accId];
accList[0].Name = 'Acc1_updated';
Account accToUpdate = Security.stripInaccessible(AccessType.UPDATEABLE, accList).getRecords()[0];
update as user accToUpdate;
6
  • Thank you for your feedback. The sample code is a simplified code snippet written to easily explain the issue. We have a number of cases where we have queried auto numbered name fields, formula fields, master-detail look fields etc. It will be a lot of work to update the code to create objects without those readonly fields and then update. Since we are not updating those fields in the objects I was hoping for a simpler alternative. Commented Nov 3, 2023 at 14:15
  • 1
    @BrijeshPopat There is no alternative. If you include the field in the query, it is in the object and will be included in the update, even if you set the value to null. Commented Nov 3, 2023 at 14:26
  • Perhaps it would be worth feeding this back to Salesforce? I have had this issue myself and it's frustrating.
    – fred
    Commented Nov 3, 2023 at 15:06
  • Security.stripInaccessible seems to be the best option available. We will try that. Thanks. Commented Nov 7, 2023 at 2:36
  • 2
    I've just sent this link to some friends at Salesforce - it does seem a bit odd that to use some new features that save code we have to add more code in other places.
    – Matt Lacey
    Commented Nov 28, 2023 at 16:07

You must log in to answer this question.

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