I couldn't find if SOQL and DML become interlinked when using WITH USER_MODE
with SOQL
and DML
both in single transaction.
I've below sample code to be triggered on a button from an LWC
:
@AuraEnabled
public static void ruleMoveOrder(String ruleId) {
My_Rule_Obj__c rule = [SELECT Id, Order__c, My_Rule__c FROM My_Rule_Obj__c WHERE Id = :ruleId WITH USER_MODE];
rule.Order__c = rule.Order__c + 1;
Database.update(rule, AccessLevel.USER_MODE);
}
This code is causing an exception like this on DML statement
line Database.update(rule, AccessLevel.USER_MODE)
:
"System.DmlException: Operation failed due to fields being inaccessible on Sobject My_Rule_Obj__c, check errors on Exception or Result!"
The Debug Logs
generated shows this information:
03:53:30.5 (21945797)|SOQL_EXECUTE_BEGIN|[76]|Aggregations:0|SELECT Id, Order__c, My_Rule__c FROM My_Rule_Obj__c WHERE Id = :tmpVar1 WITH USER_MODE
03:53:30.5 (43468810)|SOQL_EXECUTE_END|[76]|Rows:1
03:53:30.5 (43721320)|VARIABLE_SCOPE_BEGIN|[76]|rule|My_Rule_Obj__c|true|false
03:53:30.5 (43776306)|VARIABLE_ASSIGNMENT|[76]|rule|{"Id":"a1C5g000005kyuUEAQ","Order__c":1,"My_Rule__c":"a115g0000009qd2AAA"}|0xee3a1fd
03:53:30.5 (43785988)|STATEMENT_EXECUTE|[78]
03:53:30.5 (44245154)|VARIABLE_ASSIGNMENT|[78]|this.Order__c|2|0xee3a1fd
03:53:30.5 (44256849)|STATEMENT_EXECUTE|[79]
03:53:30.5 (44346702)|VARIABLE_SCOPE_BEGIN|[6]|System.AccessLevel.SYSTEM_MODE|System.AccessLevel|true|true
03:53:30.5 (44367947)|VARIABLE_SCOPE_BEGIN|[4]|System.AccessLevel.USER_MODE|System.AccessLevel|true|true
03:53:30.5 (44432606)|SYSTEM_METHOD_ENTRY|[1]|AccessLevel.AccessLevel()
03:53:30.5 (44443041)|STATEMENT_EXECUTE|[1]
03:53:30.5 (47023769)|SYSTEM_METHOD_EXIT|[1]|AccessLevel
03:53:30.5 (47219802)|DML_BEGIN|[79]|Op:Update|Type:My_Rule_Obj__c|Rows:1
03:53:30.5 (47308428)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:8
03:53:30.5 (48128599)|DML_END|[79]
03:53:30.5 (49360391)|FATAL_ERROR|System.DmlException: Operation failed due to fields being inaccessible on Sobject My_Rule_Obj__c, check errors on Exception or Result!
The error would go away and able to update correctly, as it should with below code:
@AuraEnabled
public static void ruleMoveOrder(String ruleId) {
My_Rule_Obj__c rule = [SELECT Id, Order__c, My_Rule__c FROM My_Rule_Obj__c WHERE Id = :ruleId WITH USER_MODE];
My_Rule_Obj__c rule2 = new My_Rule_Obj__c(Id = rule.Id);
rule2.Order__c = rule.Order__c + 1;
Database.update(rule2, AccessLevel.USER_MODE);
}
Why would this be? Does SOQL
query using USER_MODE
makes the rule
variable instance sort of readonly
? Can we not directly update the variable with this security system in place?
NOTE:
- Org wide sharing rule do not matter - object sharing settings are public read/write.
- Field level and Object permissions properly enabled with full CRUD and FLS permissions to edit and Read.
System.DmlException:
and I've updated that in my error message in the question. I was actually hoping this is new message syntax wheneverUSER_MODE
specific error occurs, which means, platform identified some field not assessible to user for carrying out theDML
orSOQL
operation. My Apex class Api Version is58.0
.DmlException
. It used to be that various types would be thrown across DML boundaries, but this is no longer true.