Say I want to insert a Contact with some field, and have a Trigger that populates an other field. As a developer it always felt odd that the other field value is inaccessible without re-querying the object.
Contact c = new Contact();
c.FirstName = 'Foo';
insert c;
/**
* trigger ContactTrigger on Contact (before insert) {
* Trigger.new[0].LastName = 'Bar';
* }
*/
System.debug(c.FirstName); //'Foo' (I set this one above, so the value is ok)
System.debug(c.LastName); //null (This other field would have to be 're-queried')
If you're not interested in the fields set inside a Trigger, this might only be a rare annoyance. Just a slight confuser that the Trigger
context is not the same reference as the insert
operand.
Suppose for developer convenience, we truly wanted to share those references and access fields without re-querying. I guess we could work towards it by overextending the domain layer concept:
Contact c = new Contact();
c.FirstName = 'Foo';
new ContactModel(contact).insert();
/**
* public class ContactModel {
*
* private Contact contact;
*
* public ContactModel(Contact contact) {
* this.contact = contact;
* }
*
* public void insert() {
* // before-insert logic here...
*
* this.Contact.LastName = 'Bar';
* insert this.Contact;
*
* // after-insert logic here...
* }
* }
*/
System.debug(c.FirstName); //'Foo' (I set this one above, so the value is ok)
System.debug(c.LastName); //'Bar' (I set other field in domain layer, is ok)
So with that we share the same reference. And we see the fields alright. But it comes at a cost:
- must never use native
insert
orupdate
(ironically, we could disable those with a trigger) - must write ceremony triggers to invoke the same logic outside Apex (for GUI / API operations)
- we are reinventing a fundamental platform wheel (triggers) which gives me the heebie jeebies
Am about to open source a library dealing with this.
But is there an existing pattern or native solution?
static
class property. Then instead of requerying after the DML, the entity can just be fished offContactModel.LastInserted
(for example's sake)Before Insert
trigger?? In aBefore trigger
, you can modify the contents oftrigger.new
but nothing is saved to the database until after the insert operation occurs. So what's happening makes perfect sense to me.