This article is prepared by our Salesforce Developer Dmitry Bortnovsky.
Salesforce Summer’24 release introduces a host of new features to boost developer productivity, streamline workflows, and leverage AI and automation. Key enhancements include advancements in Salesforce Flow, Apex, integration capabilities, security, and data management, along with expanded Salesforce Lightning Platform tools. Notable additions are AI-powered tools and an expanded DevOps Center, aimed at fostering more efficient, scalable, and intelligent development. This update supports both seasoned and new developers in creating better, faster, and more secure applications.
Apex Enhancements
1) Cursors for Expanded SOQL Query Result
Apex cursors, introduced in beta, provide advanced SOQL query result handling by allowing segmented processing within a single transaction. This feature supports large datasets without returning the entire result set, enabling developers to navigate the results flexibly. This feature is available in all Salesforce editions.
Cursors serve as an alternative to batch Apex, addressing its limitations, and can be used in queueable Apex job chains, enhancing their utility for high-volume data operations. They allow backward and forward navigation through result sets, providing greater control and efficiency for developers.
Cursors are stateless, created through Database.getCursor() or Database.getCursorWithBinds(), and results are fetched using Cursor.fetch(integer position, integer count). The maximum rows per cursor is 50 million, with the position and count tracked by the user. New exceptions System.FatalCursorException and System.TransientCursorException are introduced, with retries allowed for the latter. Cursor limits are consistent with API Query cursors.
Cursors are stateless, created through Database.getCursor() or Database.getCursorWithBinds(), and results are fetched using Cursor.fetch(integer position, integer count). The maximum rows per cursor is 50 million, with the position and count tracked by the user. New exceptions System.FatalCursorException and System.TransientCursorException are introduced, with retries allowed for the latter. Cursor limits are consistent with API Query cursors.
2) SOQL in Apex with Data Cloud Objects
The integration of static SOQL queries with Data Cloud Data Model Objects (DMOs) in Salesforce Apex, applicable from API version 61.0 onwards, offers a direct alternative to dynamic SOQL or ConnectAPI. This functionality enhances the efficiency of data operations by enabling the execution of static SOQL with DMOs and supporting SOQL using Database.QueryLocator or FOR loops in API version 61.0 and later.
In earlier versions, only the first 201 records are returned. Batch Apex is currently blocked against DMOs when using QueryLocators but is supported with Iterable.
The practical implementation of static SOQL with DMOs simplifies data access, as demonstrated in the following example, which fetches data from the UnifiedIndividual__dlm object based on a specified company ID:
In earlier versions, only the first 201 records are returned. Batch Apex is currently blocked against DMOs when using QueryLocators but is supported with Iterable.
The practical implementation of static SOQL with DMOs simplifies data access, as demonstrated in the following example, which fetches data from the UnifiedIndividual__dlm object based on a specified company ID:
This capability is particularly useful for high-volume data operations. Nevertheless, developers must be mindful of the potential billing implications, as running SOQL queries against DMOs can consume Data Services credits from the Data Cloud subscription. Caution is advised when using mechanisms that could result in multiple queries, such as FOR loops, query locators, and recursion.
3) Support for Five-Level Parent-to-Child Relationship SOQL Queries in Apex
The recent enhancement in Apex now supports SOQL relationship queries that can traverse up to five levels of parent-child records, significantly expanding the query capabilities for developers. Each parent-child relationship subquery counts towards the total number of aggregate queries processed in an SOQL query statement.
This change is applicable to all Salesforce editions, starting from API version 61.0 and later. With this update, SOQL parent-child relationship queries in Apex can include a parent root as the initial level and can extend to child relationships up to four levels deep from the parent root. To monitor the number of aggregate queries processed in an SOQL statement, developers can use the Limits.getAggregateQueries() method. The Limits.getLimitAggregateQueries() method returns a value of 300, indicating the maximum number of aggregate queries that can be processed within a single SOQL query statement.
The following example demonstrates an SOQL query statement that includes five levels of parent-child relationships:
This change is applicable to all Salesforce editions, starting from API version 61.0 and later. With this update, SOQL parent-child relationship queries in Apex can include a parent root as the initial level and can extend to child relationships up to four levels deep from the parent root. To monitor the number of aggregate queries processed in an SOQL statement, developers can use the Limits.getAggregateQueries() method. The Limits.getLimitAggregateQueries() method returns a value of 300, indicating the maximum number of aggregate queries that can be processed within a single SOQL query statement.
The following example demonstrates an SOQL query statement that includes five levels of parent-child relationships:
This example shows how an SOQL query can traverse from the Account object to Contacts, then to Assets, followed by WorkOrders, and finally to WorkOrderLineItems.
This hierarchical query structure allows for comprehensive data retrieval across multiple related objects in a single query, enhancing the data processing capabilities within Salesforce.
4) Evaluate Dynamic Formulas in Apex
Salesforce has introduced a significant enhancement in Apex with the support for dynamic formulas that can handle SObjects as context objects. This development is facilitated by the new Formula.builder() method, which allows developers to create and configure dynamic formulas with greater flexibility. By leveraging the Formula.builder(), developers can instantiate a FormulaBuilder to tailor formulas to their specific needs. An additional feature, the getReferencedFields() method, enables the retrieval of field names referenced within a formula, streamlining the workflow by providing quick access to relevant fields.
This capability is particularly valuable as it addresses the limitations previously associated with formula evaluation. Although formula evaluation in Apex is constrained by a character limit, there are no compile size restrictions, which allows for the creation of more complex formulas without the risk of hitting compile size limits. This enhancement applies to all Salesforce editions and is currently available as a Beta service, giving customers the option to explore its benefits under the applicable Beta Services Terms.
To illustrate the practical application of these new features, consider a scenario where a developer needs to calculate a potential discount for an Opportunity based on the opportunity amount and a user-specified discount percentage stored in a custom field. The process begins with querying the relevant Opportunity record:
This capability is particularly valuable as it addresses the limitations previously associated with formula evaluation. Although formula evaluation in Apex is constrained by a character limit, there are no compile size restrictions, which allows for the creation of more complex formulas without the risk of hitting compile size limits. This enhancement applies to all Salesforce editions and is currently available as a Beta service, giving customers the option to explore its benefits under the applicable Beta Services Terms.
To illustrate the practical application of these new features, consider a scenario where a developer needs to calculate a potential discount for an Opportunity based on the opportunity amount and a user-specified discount percentage stored in a custom field. The process begins with querying the relevant Opportunity record:
Next, a dynamic formula is constructed using the Formula.builder() method. In this example, the formula is designed to compute the discount by applying a percentage to the opportunity amount:
The withType() method specifies that the formula will use the Opportunity SObject type, while withReturnType() defines the expected result type as Decimal. The withFormula() method is used to input the actual formula logic. Once the formula is finalized using the build() method, it can be evaluated:
The result, cast to a Decimal, is then used as needed:
This process demonstrates how the dynamic formula can be constructed and evaluated within the context of an Opportunity, with field values substituted accordingly.
By using these advanced capabilities, developers can manage and manipulate complex data sets more efficiently, leading to improved data processing and application performance within Salesforce.
5) Monitoring of Apex Scheduled Jobs
Enhance your management of Apex scheduled jobs and mitigate potential limit issues with improved monitoring capabilities. This update introduces several key features aimed at optimizing the scheduling and oversight of Apex jobs.
You can now schedule Apex jobs directly from the "All Scheduled Jobs" page, streamlining job management and providing more flexibility. Additionally, the update includes options for managing jobs scheduled using cron expressions, further expanding your control over job scheduling.
A notable enhancement is the ability to view the ID of the CronTrigger object associated with each scheduled job. This added visibility allows for easier tracking and management of scheduled tasks.
To access these features, follow these steps:
These improvements aim to provide better oversight and control over Apex job scheduling, ensuring that you can effectively manage job utilization and prevent potential limit issues.
The "Pause Job" function temporarily halts the execution of a scheduled job, stopping any ongoing processes and preventing further steps from being executed until the job is resumed. This is useful for addressing issues, performing maintenance, or making necessary adjustments without permanently canceling the job.
To access these features, follow these steps:
- Navigate to Setup.
- In the Quick Find box, enter "Scheduled Jobs" and select ‘Scheduled Jobs’.
- On the "All Scheduled Jobs" page, you can review the current usage statistics for scheduled jobs and compare them against the maximum allowed limits for your organization.
These improvements aim to provide better oversight and control over Apex job scheduling, ensuring that you can effectively manage job utilization and prevent potential limit issues.
The "Pause Job" function temporarily halts the execution of a scheduled job, stopping any ongoing processes and preventing further steps from being executed until the job is resumed. This is useful for addressing issues, performing maintenance, or making necessary adjustments without permanently canceling the job.
6) Monitoring of Setup Methods with ApexTestResult
ApexTestResult rows are now automatically generated for Apex tests that utilize the @TestSetup annotation. These setup methods can be easily distinguished from other test methods by a new column, IsTestSetup, which is marked as true for such tests. This enhancement allows for better tracking and differentiation of setup methods within your test results.
Moreover, the TestSetupTime column in ApexTestRunResult now records the total setup time for all methods in a specific test run, similar to how TestTime aggregates the execution time for all test methods. This update simplifies the process of gathering details about limits and cumulative run times, which previously required parsing specific sections of the debug log.
For users who prefer not to automatically generate ApexTestResult rows for setup methods, there are options to opt out of this feature:
1. Via Setup Interface:
2. Using the Metadata API:
These updates aim to enhance monitoring capabilities for setup methods, providing clearer insights into test execution and simplifying the management of test results.
Moreover, the TestSetupTime column in ApexTestRunResult now records the total setup time for all methods in a specific test run, similar to how TestTime aggregates the execution time for all test methods. This update simplifies the process of gathering details about limits and cumulative run times, which previously required parsing specific sections of the debug log.
For users who prefer not to automatically generate ApexTestResult rows for setup methods, there are options to opt out of this feature:
1. Via Setup Interface:
- Navigate to Setup.
- In the Quick Find box, enter "Apex Settings."
- Select the option "Do not create Apex test results for @TestSetup methods."
2. Using the Metadata API:
- Programmatically disable this feature by setting the enable TestSetupSkipTestResults option in Apex Settings.
These updates aim to enhance monitoring capabilities for setup methods, providing clearer insights into test execution and simplifying the management of test results.
Lightning Web Components Enhancements
Beginning with LWC API version 61.0, component lifecycle hooks have been updated to use only native browser APIs, aligning with modern web standards. This update addresses issues such as inconsistent behavior of disconnectedCallback(), which could lead to memory leaks, particularly impacting testing code. As a result, revising your tests to accommodate these changes is recommended.
Key updates include:
Key updates include:
- Native vs. Synthetic Lifecycle Hooks: Lifecycle hooks now function differently from the previous synthetic polyfill. Components updated to the latest LWC version should have their lifecycle hooks reviewed and adjusted to ensure proper operation.
- Global Error Dispatching: Errors in connectedCallback() and disconnectedCallback() are now dispatched globally, whereas in previous versions, errors were dispatched locally.
- DOM Connection Requirement: In API version 61.0, connectedCallback() will only trigger if the component is actually connected to the DOM. Previous versions allowed this hook to activate even if the component was disconnected.
- Rendering Behavior: Components will now render only when connected to the DOM. Attempting to render a component that is not appended to the DOM may result in a null shadow root, an issue not encountered in earlier versions.
- Reinsertion of DOM Elements: Removing and reinserting elements into the DOM now causes both connectedCallback() and disconnectedCallback() to be triggered for each action. Additionally, if data bindings within the component are altered, renderedCallback() will also fire. Earlier versions did not activate these callbacks upon reordering.
This is a short overview of the most interesting (from my perspective) Salesforce Summer’24 release features, tailored especially for developers who deal with Apex and LWC.