Skip to content

SEL_Hierarchy.Selector

Class

apex
global inherited sharing class SEL_Hierarchy.Selector

Selector class that provides hierarchy operations for a specific SObject type. Created via SEL_Hierarchy.forField(parentField) - caches field metadata for efficient reuse.

Since: 1.0


Methods

MethodDescription
global Map calculateUltimateParents(Set<Id> changedRecordIds, Boolean includeDescendants)Calculates ultimate parent values for records without performing DML.
global List findAllAncestors(Id recordId)Finds all ancestors (parents, grandparents, etc.) of a record.
global Map findAllAncestors(Set<Id> recordIds)Finds all ancestors for multiple records in a single bulkified operation.
global Set findAllDescendants(Id parentId)Finds all descendants (children, grandchildren, etc.) of a record.
global Set findAllDescendants(Set<Id> parentIds)Finds all descendants for multiple parent records.
global Id findUltimateParent(Id recordId)Finds the ultimate parent (root ancestor) for a record.
global Map findUltimateParents(Set<Id> recordIds)Finds ultimate parents for multiple records in a single bulkified operation.
global List propagateToDescendants(Set<Id> changedRecordIds, SObjectField ultimateParentField)Updates all descendants of changed records with the new ultimate parent reference.
global SEL_Hierarchy.Selector withMaxDepth(Integer depth)Sets the maximum hierarchy depth for this selector.

Method Details

calculateUltimateParents

apex
global Map<Id, Id> calculateUltimateParents(Set<Id> changedRecordIds, Boolean includeDescendants)

Calculates ultimate parent values for records without performing DML. Returns a map that can be used for updates or analysis.

Parameters:

  • changedRecordIds (Set) - Records whose parent has changed.
  • includeDescendants (Id) - Whether to include all descendants in the result.

Returns: Id - Map of record Id to its ultimate parent Id.

Since: 1.0

Example:

apex
Map<Id, Id> ultimateParents = SEL_Hierarchy.forField(Account.ParentId)
    .calculateUltimateParents(changedAccountIds, true);

findAllAncestors

apex
global List<SObject> findAllAncestors(Id recordId)

Finds all ancestors (parents, grandparents, etc.) of a record. Returns ancestors ordered from immediate parent to ultimate parent (root).

Parameters:

  • recordId (Id) - The Id of the record to find ancestors for.

Returns: SObject - List of ancestor SObjects ordered from immediate parent to ultimate parent. Empty list if record has no parent.

Since: 1.0

Example:

apex
// Account hierarchy: GrandChild -> Child -> Parent -> GrandParent (no parent)
List<Account> ancestors = (List<Account>)SEL_Hierarchy.forField(Account.ParentId)
    .findAllAncestors(grandChildAccountId);
// Returns: [Child, Parent, GrandParent] - ordered from closest to furthest

findAllAncestors

apex
global Map<Id, List<SObject>> findAllAncestors(Set<Id> recordIds)

Finds all ancestors for multiple records in a single bulkified operation.

Parameters:

  • recordIds (Set) - Set of record Ids to find ancestors for.

Returns: SObject - Map of record Id to its list of ancestors. Each list is ordered from immediate parent to ultimate parent.

Since: 1.0

Example:

apex
Set<Id> accountIds = new Set<Id>{acc1.Id, acc2.Id};
Map<Id, List<SObject>> ancestorsByRecord = SEL_Hierarchy.forField(Account.ParentId)
    .findAllAncestors(accountIds);
for(Id accountId : accountIds)
{
    List<SObject> ancestors = ancestorsByRecord.get(accountId);
    System.debug('Ancestors for ' + accountId + ': ' + ancestors);
}

findAllDescendants

apex
global Set<Id> findAllDescendants(Id parentId)

Finds all descendants (children, grandchildren, etc.) of a record.

Parameters:

  • parentId (Id) - The Id of the parent record.

Returns: Id - Set of all descendant record Ids (does not include the parent).

Since: 1.0

Example:

apex
Set<Id> allDescendants = SEL_Hierarchy.forField(Account.ParentId)
    .findAllDescendants(parentAccountId);

findAllDescendants

apex
global Set<Id> findAllDescendants(Set<Id> parentIds)

Finds all descendants for multiple parent records.

Parameters:

  • parentIds (Set) - Set of parent record Ids.

Returns: Id - Set of all descendant record Ids (does not include the parent Ids).

Since: 1.0

Example:

apex
Set<Id> parentIds = new Set<Id>{parent1.Id, parent2.Id};
Set<Id> allDescendants = SEL_Hierarchy.forField(Account.ParentId)
    .findAllDescendants(parentIds);

findUltimateParent

apex
global Id findUltimateParent(Id recordId)

Finds the ultimate parent (root ancestor) for a record. Traverses up the hierarchy until a record with no parent is found.

Parameters:

  • recordId (Id) - The Id of the record to find the ultimate parent for.

Returns: Id - The Id of the ultimate parent, or the record's own Id if it has no parent.

Since: 1.0

Example:

apex
// Account hierarchy: GrandChild -> Child -> Parent -> GrandParent (no parent)
Id ultimateParent = SEL_Hierarchy.forField(Account.ParentId)
    .findUltimateParent(grandChildAccountId);
// Returns: GrandParent's Id

findUltimateParents

apex
global Map<Id, Id> findUltimateParents(Set<Id> recordIds)

Finds ultimate parents for multiple records in a single bulkified operation. Optimizes SOQL by querying in batches and traversing multiple parent levels per query.

Parameters:

  • recordIds (Set) - Set of record Ids to find ultimate parents for.

Returns: Id - Map of record Id to its ultimate parent Id. Records with no parent map to themselves.

Since: 1.0

Example:

apex
Set<Id> accountIds = new Set<Id>{acc1.Id, acc2.Id, acc3.Id};
Map<Id, Id> ultimateParents = SEL_Hierarchy.forField(Account.ParentId)
    .findUltimateParents(accountIds);
for(Id accountId : accountIds)
{
    System.debug('Ultimate parent: ' + ultimateParents.get(accountId));
}

propagateToDescendants

apex
global List<SObject> propagateToDescendants(Set<Id> changedRecordIds, SObjectField ultimateParentField)

Updates all descendants of changed records with the new ultimate parent reference. Typically used in trigger context when a record's parent changes.

Use Case: When Account A's parent changes, all of A's children (and their children) need their UltimateParent__c field updated to point to A's new ultimate parent.

Parameters:

  • changedRecordIds (Set) - Records whose parent has changed.
  • ultimateParentField (Id) - The field to store the ultimate parent reference.

Returns: SObject - List of updated records (not yet committed to database).

Since: 1.0

Example:

apex
// In a trigger action when parent changes:
List<SObject> updates = SEL_Hierarchy.forField(Account.ParentId)
    .propagateToDescendants(changedAccountIds, Account.UltimateParent__c);
update updates;

withMaxDepth

apex
global SEL_Hierarchy.Selector withMaxDepth(Integer depth)

Sets the maximum hierarchy depth for this selector. Useful for limiting traversal in known shallow hierarchies or testing.

Parameters:

  • depth (Integer) - Maximum levels to traverse.

Returns: SEL_Hierarchy.Selector - This selector for method chaining.

Since: 1.0

Example:

apex
SEL_Hierarchy.Selector hierarchy = SEL_Hierarchy.forField(Account.ParentId)
    .withMaxDepth(10);