Select your language

  • Davide Gammone


Salesforce Spring '21 Release Top Development Features

Salesforce Spring '21 is bringing many features that can be very useful. In this post I will show some of my favorite features for Developers. You can find all the new Salesforce Spring '21 Release Notes here.

Use with sharing for @AuraEnabled Apex Controllers with Implicit Sharing (Update, Enforced)

This update changes the behavior of @AuraEnabled Apex controllers that don’t specify with sharing or without sharing to default to with sharing. Salesforce decided to ensure that Lightning components are secure by default, and created this new update that defaults to with sharing for @AuraEnabled Apex classes used by Aura components or Lightning web components.

Create a Lightning Web Component Action (Pilot)

Create a Lightning Web Component (LWC) and use it as a quick action. Lightning Web Component actions work side by side on your pages along with Lightning component and Visualforce actions. LWC actions offer advantages such as the ability to easily customize headers and footers, and to create actions that have no UI representation. Available to orgs that enable the pilot feature.

Attach Actions to Asynchronous Apex Jobs Using Transaction Finalizers (Beta)

With Spring ’21, the Transaction Finalizers feature is in beta. A new limit establishes that a Queueable job that failed due to an unhandled exception can only be successively re-enqueued five times by a Transaction Finalizer. This limit applies to a series of consecutive Queueable job failures. The counter is reset when the Queueable job completes without an unhandled exception. Finalizers can be implemented as an inner class. Also, you can implement both Queueable and Finalizer interfaces with the same class.

The System.FinalizerContext interface contains four methods:

  • getAsyncApexJobId method: Returns the ID of the Queueable job for which this finalizer is defined.
  • getRequestId method: Returns the request ID shared by both the finalizer execution and the Queueable job to which the finalizer is attached. This shared ID helps in filtering logs of a Queueable job and its attached finalizer.
  • getResult method: Returns the System.ParentJobResult enum, which represents the result of the parent asynchronous Apex Queueable job to which the finalizer is attached. Valid values for the enum are SUCCESS, and UNHANDLED_EXCEPTION.
  • getException method: Returns the exception with which the Queueable job failed when getResult is UNHANDLED_EXCEPTION, null otherwise.

To attach actions to your Queueable jobs, you must implement the FinalizerContext interface. Only one finalizer instance can be attached to any Queueable job. You can enqueue a single asynchronous Apex job (Queueable, future, or batch) in the finalizer’s implementation of the execute method. Callouts are allowed in finalizer implementations. For more information on implementing Transaction Finalizers, including examples, see Transaction Finalizers (Beta) in Apex Developer Guide.

Flag Invocable Apex Methods That Make Callouts

For invocable actions that perform callouts, you can now add a callout attribute to the invocable Apex method annotation. With this information, a flow calling the action knows how to manage the transaction at run time. To flag callouts in Apex methods annotated with @InvocableMethod, add the callout attribute to the annotation and set it to true.

@InvocableMethod(callout=true, label="My Action Label")

If your action makes a callout, set the callout attribute to true. If the action is executed by a flow, at run time the flow determines how to successfully execute the action, in a new transaction or in the currently running transaction. If the callout attribute is set to false, the action is flagged to safely perform in the transaction regardless of whether the transaction has uncommitted work.

Query Cursors Optimized for Improved Performance

Apex optimized the way it uses query cursors. In cases such as SOQL queries that use a for loop, Apex no longer generates or uses query cursors internally. Instead, records are buffered in memory for improved performance and reduced query cursor contention. This optimization doesn’t apply to Batch Apex queries.

Obtain a map containing all custom metadata records or a single record sObject for a custom metadata type

Use the new Apex getAll(), getInstance(recordId), getInstance(qualifiedApiName), or getInstance(developerName) methods to retrieve custom metadata type records. So no more SOQL query to fetch custom metadata records.

Map<String, City__mdt> allCities = City__mdt.getAll();

The sample below returns a single record sObject for the custom metadata type named Games_mdt with record ID specified as m00000000000001.

Games__mdt mc = Games__mdt.getInstance('m00000000000001');

Convert an 18-character Id value to a 15-character case-sensitive string

Use the to15() method in the System.Id class. This method uses the case-sensitivity checksum in the 18-character Id value to fix any mangled casing and returns a 15-character case-sensitive string.


String Id_15_char = '0D5B000001DVM9t';
String Id_18_char = '0D5B000001DVM9tkAh';
ID testId = Id_18_char;

From version 51.0 onwards, the format() method in the System.String class supports single quotes in the stringToFormat parameter

The String.format() method supports single quotes in the stringToFormat parameter and returns a formatted string using the formattingArguments parameter. In version 50.0 and earlier, single quotes weren’t supported.

From version 51.0 onwards, the hashCode() method in the System.System class returns the same hashCode for identical Id values

In version 50.0 and earlier, identical Id values didn’t always generate the same hashCode value.

SOQL, select all fields

Salesforce Object Query Language (SOQL) now makes it easy to include pre-defined groupings of fields within a query statement using the new FIELDS() function. Use FIELDS(ALL), FIELDS(STANDARD), or FIELDS(CUSTOM) in your SELECT statements.

FROM Account
WHERE Name = 'MyAccount'

GDPR Alert

This site uses cookies, including third-party requests, to offer you services in line with your preferences. By closing this banner, scrolling this page or clicking any element, you consent to the use of cookies. If you want to learn more or opt out of all or some cookies, click on Privacy Policy...