(Pic Courtesy : Salesforce)
1. Enhanced Apex Capabilities
Five-Level SOQL Relationship Queries: Salesforce now allows SOQL relationship queries to traverse up to five levels of parent-child records directly within Apex, aligning with previous support available through REST APIs. This enhancement is particularly useful for retrieving deeply nested data. Here’s a sample SOQL query demonstrating this feature:Example:
List<Account> accounts = [SELECT Name, (SELECT LastName, (SELECT AssetLevel, (SELECT Description, (SELECT LineItemNumber FROM WorkOrderLineItems) FROM WorkOrders) FROM Assets) FROM Contacts) FROM Account];
Each parent-child relationship subquery counts as an aggregate query, and the limit for these in an Apex transaction is 300 for synchronous transactions. To track aggregate queries, use Limits.getAggregateQueries().
2. FormulaEval Class (Beta)
The FormulaEval class in Apex has been enhanced to support sObjects in addition to user-defined Apex classes. This class enables dynamic formula evaluation at runtime. Here’s a practical example:
Account account = new Account(); account.Name = 'Sample Account'; account.Rating = 'Hot'; String formulaExpression = 'ISPICKVAL(Rating, \'Hot\')'; FormulaEval.FormulaInstance formula = Formula.builder() .withReturnType(FormulaEval.FormulaReturnType.Boolean) .withType(Account.class) .withFormula(formulaExpression) .build(); System.debug((boolean)formula.evaluate(account)); // Expected output: true
3. Apex Cursors (Beta)
Apex cursors facilitate processing large SOQL query results in manageable chunks within a single transaction. This is particularly useful for handling extensive data sets. Here’s an example of using Apex cursors with Queueable:
public class FileProcessingQueueable implements Queueable { private Database.Cursor fileQueryCursor; private Integer position; public FileProcessingQueueable() { fileQueryCursor = Database.getCursor('SELECT Id, Title, ContentDocumentId, VersionData FROM ContentVersion WHERE CreatedDate = LAST_N_DAYS:100'); position = 0; } public void execute(QueueableContext ctx) { List<ContentVersion> chunk = fileQueryCursor.fetch(position, 200); position += chunk.size(); for (ContentVersion cv : chunk) { String fileName = cv.Title; Blob fileBody = cv.VersionData; System.debug('Processing file: ' + fileName); } if (position < fileQueryCursor.getNumRecords()) { System.enqueueJob(this); } } }
4. InvocableVariable Modifiers
The new defaultValue and placeholder Text modifiers for InvocableVariable allow you to set default values and provide custom placeholder text for input parameters in invocable actions. Here’s an example:
public class MyFlowAction { public class MyInvocableVariable { @InvocableVariable(label='Notes', description='Additional notes for processing.', placeholderText='Enter notes here...', defaultValue='Account notes') public String notes; } @InvocableMethod(=label='Process Account', description='Process an account record.') public static void processAccount(List<MyInvocableVariable> inputs) { // Your logic here } }
5. getRelationshipOrder Method Support for Standard Fields
The getRelationshipOrder method in DescribeFieldResult now returns 0 for primary relationship fields and 1 for secondary relationship fields for standard fields, enhancing data relationship management.
6. Improved Apex Exception Emails
Exception emails generated by Apex now include detailed information such as the organization name, user name, and My Domain name, improving the context for debugging.
6. Efficient Monitoring of Apex Scheduled Jobs
Salesforce has streamlined the monitoring and management of scheduled Apex jobs. The All Scheduled Jobs page now displays the associated CronTrigger object ID and provides enhanced error messages when attempting to delete classes used by scheduled or batch jobs.
7. Lightning Web Components (LWC) Enhancements
a. URL-Addressable LWC Components:You can now make Lightning Web Components (LWCs) URL-addressable using the lightning__UrlAddressable target, allowing navigation directly to these components with custom state parameters.
b. Utility Bar API for LWCs:The lightning/platformUtilityBarApi module introduces methods for managing utilities within the utility bar, making it easier to build and manage utility bar components.
8. The latest API version 61.0 brings several enhancements:
a. ElementInternals Web API: Allows custom form controls to integrate seamlessly with standard HTML forms, making them more accessible and functional.
b. Native Browser API Lifecycle Hooks: Adopting native browser APIs for lifecycle hooks to ensure better performance and resolve memory leaks.
c. Third-Party Web Components Integration (Beta): Integrate third-party web components into LWCs without needing to rebuild them, facilitating more seamless integrations.
d. Base Component Updates for Native Shadow DOM Support: Salesforce has updated base components in preparation for future support of native Shadow DOM.
e. Avoid Styling Anti-Patterns: Optimize render times by avoiding anti-patterns that lead to inefficient styling practices.
f. Improved Modal Navigation Behavior: The lightning/navigation module now supports setting replace to true to automatically close previous modals when navigating.
g. New LWC Components for Field Service Mobile: Leverage new LWCs using NFC and Space Capture plug-ins to enhance data capture and streamline processes in Field Service mobile applications.
9. Data Cloud Enhancements
Static SOQL for Data Cloud DMOs: Developers can now use static SOQL with Data Cloud data model objects (DMOs) in Apex. This addition simplifies data retrieval with strongly typed results. Here’s an example:
List<Solar_Panel_Event__dlm> solarPanelEvents = [ SELECT Id, DataSource__c, DataSourceObject__c, ac_current__c, ac_voltage__c, battery__c, CustomerId__c, date_time__c, dc_current__c, dc_voltage__c FROM Solar_Panel_Event__dlm WHERE CustomerId__c = :customerId];
10. Mocking SOQL Queries for DMOs
Salesforce now supports mocking SOQL query responses for DMOs in Apex unit tests, enhancing test coverage and reliability. Here’s an example test class:
@IsTest public class TestSolarDeviceEventsManager { @IsTest public static void testMockSoql() { SoqlStubProvider stub = new SolarPanelEventsSoqlStub(); Test.createSoqlStub(Solar_Panel_Event__dlm.sObjectType, stub); Assert.isTrue(Test.isSoqlStubDefined(Solar_Panel_Event__dlm.sObjectType)); Test.startTest(); String customerId = '12345abd'; List<Solar_Panel_Event__dlm> solarPanelEvents = EventManager.getSolarPanelEvents(customerId); Test.stopTest(); Assert.isTrue(solarPanelEvents.size() > 0); } private class SolarPanelEventsSoqlStub extends SoqlStubProvider { public override List<SObject> handleSoqlQuery( Schema.SObjectType sObjectType, String query, Map<String, Object> bindVariables) { Assert.areEqual(Solar_Panel_Event__dlm.sObjectType, sObjectType); String customerId = ''; if (bindVariables.containsKey('tmpVar1')) { customerId = (String)bindVariables.get('tmpVar1'); } Solar_Panel_Event__dlm dmo = (Solar_Panel_Event__dlm)Test.createStubQueryRow( sObjectType, new Map<String, Object>{ 'ac_current__c' => 12, 'ac_voltage__c' => 440, 'battery__c' => 1, 'CustomerId__c' => '12345abd', 'date_time__c' => System.now(), 'dc_voltage__c' => 1 } ); return new List<SObject>{dmo}; } } }
11. Testing Data Cloud-Triggered Flows
You can now run tests for Data Cloud-triggered flows, allowing developers to validate their functionality without manually configuring debug parameters for each test run.
12. Data Lookup Relationships
Salesforce has introduced the ability to create lookup relationships between DMOs and a select number of CRM objects. This feature allows querying DMOs from Apex or creating related lists, simplifying complex data models.
13. Enriching Data Cloud with CRM Objects
Data Cloud Related List Enrichments now support Account objects in addition to Leads and Contacts, enabling more comprehensive data enrichment and access.
14. Einstein Query Language (EQL) Support
EQL now supports querying DMOs, expanding the scope of EQL to include these objects for more flexible data analysis.