This is the reference for this code :http://bobbuzzard.blogspot.co.nz/2012/03/create-parent-and-child-records-in-one.html
What exactly happens behind the scenes,when we say
Account acc=new Account(Name='Blog Acc 901', Master_Id__c='Blog Acc 9001');
Contact cont=new Contact(FirstName='Bob901', LastName='Buzzard', Account=new Account(Master_Id__c='Blog Acc 9001'));
Master_id__c is the external field.I understand specifying external id at somepoint helps to find it is pointing to acc.(like we specify external ids,instead of ids in dataloader)
My main doubts are
*-what exactly is getting saved in Account foreign key reference field in Contact?
is it the Database memory location for that record?
*In this particular eg: when we say Account = new Account(Master_ID__C = 'abcd') ,what exactly is happening in heap memory and at what point does it realise it is pointing to acc
*Is external id,the only type of field that can be specified in this scenario?
Best Answer
We are specifying three objects to be created in memory. The first is an account (
acc
), the second is a contact (cont
), and the third is another account (cont.account
).It's a normal memory reference to a heap location. Every object occupies memory on the heap, and so therefore each usage of the word
new
creates a new object on the heap. Imagine the heap looks like this after running those three lines of code:Let's be clear:
Cont.Account
(0x0002) is notacc
(0x0001), and the two references never point to the same heap address, even after inserting the new records. You can prove this by checking thatSystem.assert(acc!==cont.account)
.At no point in the data execution (in this scenario) does Apex Code "realize" that
cont.Account
is pointing toacc
, because Apex Code considers them two discrete memory objects, even if they are literally "pointing" to the same database record.The database itself knows that an External ID can be used to reference a record manually without an ID, and so when it encounters the
Master_ID__c
value, it is intelligent enough to consult the External ID index and acquire the appropriate ID for the given record.You can specify any field you want to, but only the External ID value will be considered for determining the correct record ID to use. This is useful for certain kinds of constructs where you want to be able to reference the related object later without a map. Here's an example trigger that utilizes this method:
We are creating a new order, either from the UI or data loader. We want to report to the funnel, so we backfill an opportunity. We do this in four steps:
Steps 1-3 occur in the before insert event, so Trigger.newMap has no keys, because the records have not yet been assigned an ID. In this case, we use the relationship as a storage device to temporarily associate the opportunity to the order long enough for us to create the record.
Step 4 occurs in the after insert event, so we now know what the ID for each Order is, and its auto-number value. We didn't know this initially, so we couldn't have specified this when creating the opportunity, but we wanted to store the data back in the order, which we couldn't have done in the after insert event, because the records would already be read-only.
In this way, you can use the mechanism as temporary storage, but you must remember to save the data somewhere permanent if you need to know this data later, because the association would disappear when the trigger ends.