1

I'm trying some of the new features to Apex to automatically apply User Access. I cannot get an update to work that worked from with a require "update" or "Database.update()".

Event eventToCancel = [SELECT Id, Subject,
            TYPEOF Owner WHEN USER THEN LanguageLocaleKey, LocaleSidKey, TimeZoneSidKey  END
            FROM Event
            WHERE Id=:currentRecord.Id 
            WITH SECURITY_ENFORCED
            limit 1];
list<SObject> updateEventList = new list<SObject>{eventToCancel};
Database.update(updateEventList, true, System.AccessLevel.USER_MODE);

I think what it is complaining about is that the record may have both an Owner reference and an OwnerId. But, a simple "update updateEventList" statement works just fine.

I'm wondering if the access level user mode just doesn't have all the kinds worked out. Or, like many things in SF, what looks like a powerful feature turns out to be something you have to jump through hoops through to use.

2 Answers 2

1

This behavior occurs because you're allowed to reference a parent object in order to link a record. For example, let's say you want to insert an account and a contact in a single statement. It is legal to do this:

sObject[] records = new sObject[0];
records.add(new Account(Name='Demo',Account_Number__c=123));
records.add(new Contact(LastName='Person', Account=new Account(Account_Number__c=123));
insert records;

This works for any External ID field, as well as some Name fields that are considered eligible for this feature.

In general, you should not use an sObject that has parent relationships, because it triggers this specific feature. Note that this also works in the REST and SOAP API interfaces as well, and is not unique to Apex.

Note that if the external ID value isn't unique, or doesn't exist, you'll get an error regarding not being able to match the field reference to a unique record.

1
  • However the DML works fine with a simple update statement. It only fails with "update as user". This succeeds.... Event sfEvent = [ SELECT Id, Owner.Name FROM Event ORDER BY CreatedDate LIMIT 1]; update sfEvent; This fails... Event sfEvent = [ SELECT Id, Owner.Name FROM Event ORDER BY CreatedDate LIMIT 1]; update as user sfEvent;
    – Ken
    Commented Jul 10 at 11:45
1

It appears that there is some restriction if you have references to parent objects. That makes the feature pretty much useless unless you want to rewrite any code where parent fields are needed.

The following code fails...

Event sfEvent = [ SELECT Id, Owner.Name FROM Event ORDER BY CreatedDate LIMIT 1];
update as user sfEvent;

The error is...

System.DmlException: Update failed. First exception on row 0 with id 00U46000007zGV1EAM; first error: INVALID_FIELD, Cannot specify both an external ID reference Owner and a salesforce id, OwnerId: []

The following code succeeds...

Event sfEvent = [ SELECT Id FROM Event ORDER BY CreatedDate LIMIT 1];
update as user sfEvent;

Including the parent reference and updating without "as user" succeeds. The code below works fine.

Event sfEvent = [ SELECT Id, Owner.Name FROM Event ORDER BY CreatedDate LIMIT 1];
update sfEvent;

I would think that "update as user" would behave like "update" when the executing User has access to all objects in play.

You must log in to answer this question.

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