---
schema_version: "1"
id: 149e90abbe85114d00cadaa050eae529e024dea52eeb32eb81d4afe67117b4eb
title: Accessing sObject Fields Through Relationships
collection: legacydeveloper
version: current
locale: en-us
portal_url: https://docs.salesforce.com/legacydeveloper/current/en-us/apexcode/langCon_apex_SObjects_field_relationships.md
canonical_url: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_SObjects_field_relationships.htm
source_site: developer.salesforce.com
content_type: documentation
content_hash: 3975c8b2cb62813edaf2b17ce1769ddb7cb2bc5f37c2773c7066e9fd530fa9e1
---
# Accessing sObject Fields Through Relationships

sObject records represent relationships to other records with two fields: an ID and an address that points to a representation of the associated sObject. For example, the Contact sObject has both an AccountId field of type ID, and an Account field of type Account that points to the associated sObject record itself.

The ID field can be used to change the account with which the contact is associated, while the sObject reference field can be used to access data from the account. The reference field is only populated as the result of a SOQL or SOSL query (see note).

For example, the following Apex code shows how an account and a contact can be associated with one another, and then how the contact can be used to modify a field on the account:

![Note](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/images/icon_note.png)

#### Note

To provide the most complete example, this code uses some elements that are described later in this guide:

- For information on insert and update, see [Insert Statement](https://developer.salesforce.com/docs/atlas.en-us.264.0.apexref.meta/apexref/apex_dml_section.htm) and [Update Statement](https://developer.salesforce.com/docs/atlas.en-us.264.0.apexref.meta/apexref/apex_dml_section.htm).

Account a = new Account(Name = 'Acme');
insert as user a;  // Inserting the record automatically assigns a 
           // value to its ID field
Contact c = new Contact(LastName = 'Weissman');
c.AccountId = a.Id;
// The new contact now points at the new account
insert as user c;

// A SOQL query accesses data for the inserted contact, 
// including a populated c.account field
c = \[SELECT Account.Name FROM Contact WHERE Id = :c.Id WITH USER\_MODE\];

// Now fields in both records can be changed through the contact
c.Account.Name = 'salesforce.com';
c.LastName = 'Roth';

// To update the database, the two types of records must be 
// updated separately
update as user c;         // This only changes the contact's last name
update as user c.Account; // This updates the account name

![Note](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/images/icon_note.png)

#### Note

The expression c.Account.Name, and any other expression that traverses a relationship, displays slightly different characteristics when it is read as a value than when it is modified:

- When being read as a value, if c.Account is null, then c.Account.Name evaluates to null, but does _not_ yield a NullPointerException. This design allows developers to navigate multiple relationships without the tedium of having to check for null values.
- When being modified, if c.Account is null, then c.Account.Name _does_ yield a NullPointerException.

In SOSL, you would access data for the inserted contact in a similar way to the SELECT statement used in the previous SOQL example.

List<List<SObject>> searchList = \[FIND 'Acme' IN ALL FIELDS RETURNING Contact(id,Account.Name)\]

In addition, the sObject field key can be used with insert, update, or upsert to resolve foreign keys by external ID. For example:

Account refAcct = new Account(externalId\_\_c = '12345');

Contact c = new Contact(Account = refAcct, LastName = 'Kay');

insert as user c;

This inserts a new contact with the AccountId equal to the account with the external\_id equal to ‘12345’. If there is no such account, the insert fails.

![Tip](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/images/icon_note_tip.png)

#### Tip

The following code is equivalent to the code above. However, because it uses a SOQL query, it is not as efficient. If this code was called multiple times, it could reach the execution limit for the maximum number of SOQL queries. For more information on execution limits, see [Execution Governors and Limits](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_gov_limits.htm "Because Apex runs in a multitenant environment, the Apex runtime engine strictly enforces limits so that runaway Apex code or processes don’t monopolize shared resources. If some Apex code exceeds a limit, the associated governor issues a runtime exception that can’t be handled.").

Account refAcct = \[SELECT Id FROM Account WHERE externalId\_\_c='12345' WITH USER\_MODE\];

Contact c = new Contact(Account = refAcct.Id);

insert as user c;

- [← Previous](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_SOQL_working_with_results.htm "Working with SOQL and SOSL Query Results")
- [Next →](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_SOQL_foreign_key.htm "Understanding Foreign Key and Parent-Child Relationship SOQL Queries")