Skip to main content

SF-0036 · Concept · Medium

What is self-relationship or self lookup?

✓ Verified by Vikas Singhal · Last reviewed 5/17/2026

A self-relationship (or self-lookup) is a relationship field on an object that points back to the same object. The most common shape is a Lookup, but you can technically also do self-master-detail (rare and tricky). Self-relationships model hierarchies, predecessors, parent-child structures, and tree-like data — all within one entity.

Canonical example: Account.ParentId

The standard Account object ships with ParentId, a self-lookup pointing back to Account. This is how you build a corporate hierarchy:

Acme Corp (top)
├── Acme North America (Parent = Acme Corp)
│   ├── Acme USA (Parent = Acme North America)
│   └── Acme Canada (Parent = Acme North America)
└── Acme Europe (Parent = Acme Corp)
    ├── Acme UK
    └── Acme Germany

The “View Hierarchy” button on Account uses ParentId to traverse and display the tree.

Other common self-relationship patterns

  • Position__c → Position__c (Reports_To) — corporate org chart on a custom Position object
  • Task__c → Task__c (Depends_On) — project task dependencies / predecessors
  • Knowledge_Article__c → Knowledge_Article__c (Supersedes) — version chain
  • Folder__c → Folder__c (Parent_Folder) — nested folder structure
  • Category__c → Category__c (Parent_Category) — N-level taxonomy

How to create one

  1. Open the object (Position__c).
  2. Add a new field of type Lookup Relationship.
  3. In “Related To,” pick the same object (Position__c).
  4. Field label: e.g., “Reports To”; API name: Reports_To__c.
  5. Configure the related-list label that will appear on the parent (e.g., “Direct Reports”).
  6. Save.

Now each Position can reference another Position as its parent. The “Direct Reports” related list on a Position shows its children automatically.

Self master-detail — possible but watch out

You can create a master-detail to the same object, but you should think carefully:

  • Cascade delete becomes recursive — deleting a parent deletes its children, which deletes their children, etc.
  • Sharing is Controlled by Parent, which means an org-wide chain of inheritance up to the root
  • The Salesforce 3-level master-detail limit applies — a child can be a detail of one parent and master of another, but only 3 deep

For most hierarchical needs, self-lookup is the right call. Reserve self-master-detail for truly tightly coupled hierarchies (rare).

Preventing cycles

This is the most important caveat with self-lookups. Salesforce does not automatically prevent cycles on a generic self-lookup (the User Hierarchical Relationship is the only one that does this for you). Without protection, an admin could set:

Position A.Reports_To = B
Position B.Reports_To = A   ← cycle!

Or worse:

A → B → C → A

This breaks any code that walks the chain (infinite loop) and corrupts your hierarchy logic. Common solutions:

  1. Validation rule comparing record Id to lookup Id — at least catches A → A:
    Reports_To__c = Id
  2. Trigger that, on every save, walks the proposed chain upward and errors if it encounters the current record’s Id. Use a Set<Id> of visited Ids and abort once the set’s size suggests a loop.
  3. Flow with the same logic, declaratively — usable for shallow hierarchies.

Querying self-relationships

SOQL handles parent traversal naturally with the relationship name:

SELECT Id, Name, Parent.Name, Parent.Parent.Name
FROM Account
WHERE Id = :accountId

You can go up to 5 levels of parent traversal in a single SOQL query. For deeper trees, query iteratively in Apex or use a recursive flow.

For child traversal (one level only):

SELECT Id, Name, (SELECT Id, Name FROM ChildAccounts)
FROM Account
WHERE Id = :rootId

ChildAccounts is the standard child-relationship name on the self-lookup. For custom self-lookups, you set this name yourself when creating the field.

Reports on self-relationships

Salesforce reports support self-joined reports up to a fixed depth — the “Account with Parent Account” pattern. For arbitrary-depth tree reports, you’ll need a custom report type, or you’ll pre-compute a flattened “Root Account” formula and group by that.

Summary

Self-relationship = a lookup where the object refers back to itself. Used for hierarchies and parent-child within one object. Cycle prevention is your responsibility for everything except the User Hierarchical Relationship.

Verified against: Salesforce Help — Object Relationships Overview. Last reviewed 2026-05-17.