One of the most startling things I ever learned from @BobBuzzard is that you can update a lookup by using the name pointing field. At least, I thought that's what I learned, until a recent debate cast some doubt on that finding. That debate went:
Me: What BB says is that you can in fact use the
__r fields to specify the relationship using external Id. It looks to me like you're saying you can't use the
__r fields to specify the relationship?
@AdrianLarson That's not what I read in his post. A
__r is a reference (pointer) to the other object. An external Id is an alternate key where you can specify the value at both sides (rather than requiring the Id that is only available after the first object is inserted.
Me: He essentially says you can
insert new Contact(FirstName='Bob', LastName='Buzzard', Account=new Account(External__c='key'));. He's using standard relationships, but that means you can set the lookup via the pointer. No?
@AdrianLarson No, I'm confident you can't. Suggest you try it if you wan [sic] to be sure.
I couldn't find any such material on our exchange, so I figured this is a good time to vet this seemingly amazing finding and make it more discoverable here. It's over four years old and looks like it is still not common knowledge.
First, I highly recommend you read Bob's post for yourself. He's a much better writer than I am. Also, Salesforce documents this behavior in Relating Records by Using an External ID and Creating Parent and Child Records in a Single Statement Using Foreign Keys.
To relate a record to its parent record with an external ID, the parent object must have a custom field marked as External ID. Create the parent sObject with an external ID value, and then set this record as a nested sObject on the record you want to link.
This example shows how to relate a new opportunity to an existing account. The account has an external ID field, named MyExtID, of type text. Before the new opportunity is inserted, the Account record is added to this opportunity as a nested sObject through the Opportunity.Account relationship field. The Account sObject contains only the external ID field.
Opportunity newOpportunity = new Opportunity(
// Create the parent record reference.
// An account with this external ID value already exists.
// This sObject is used only for foreign key reference
// and doesn't contain any other fields.
Account accountReference = new Account(
// Add the nested account sObject to the opportunity.
newOpportunity.Account = accountReference;
// Create the opportunity.
Database.SaveResult results = Database.insert(newOpportunity);
Still, the question where this issue came up was specifically about
__r name pointing references (custom fields), so here is a demonstration that it works with such fields as well.
insert new MyObject__c(Parent__r = new Parent__c(External__c='1'));
Sure does work. Sweet.