[SalesForce] Setting field value in sObject constructor vs after instantiation

My question:

Why can you set a value of a field like ParentId on the CaseTeamTemplateRecord object in the constructor during instantiation, but receive an exception if you set the value after instantiation?

The situation:

We are allowing community users to create case teams on cases via apex. The class is marked as WITH SHARING but the insertion of the records occurs in a class marked as WITHOUT SHARING. This was done due to Community Users not having DML permissions on the CaseTeamTemplateRecord object. So it will allow DML as long as the insertion is done in a class marked as WITHOUT SHARING.

When the community user tried to add a case team to the case, we received this message:

Field is not writeable: CaseTeamTemplateRecord.ParentId

I changed the code to set the ParentId in the constructor of the sObject instead of after instantiating the sObject … and it worked.

The offending code block (ParentId set after instantiation of sObject):

CaseTeamTemplateRecord cttr = new CaseTeamTemplateRecord();
cttr.ParentId = case.Id; // Exception thrown here
cttr.TeamTemplateId = teamTemplate.Id;

The working code block (ParentId set in sObject constructor):

CaseTeamTemplateRecord cttr = new CaseTeamTemplateRecord(
    ParentId = case.Id,
    TeamTemplateId = teamTemplate.Id
);

Best Answer

It's because the intent is for developers to use constructors as intended. Using the sObject constructor is meant to signify that you're creating a new record, and accessing those fields afterwards means you're trying to update a record.

This is enforced as a compiler restriction to reduce the odds that a developer will try to set a field that can only be set on create. I personally find that this restriction is overly ambitious, because the object can't know ahead of time if you're going to insert, update, delete, display on a page...

Regardless, you should always initialize sObject fields using the name-value pair constructor when possible, as it is at least 2x more efficient against CPU governor limits.

Related Topic