Hi,
Here we are going to learn
How to do two composite graph requests each create an Account and then create related records:
Endpoint Url:
- <instance.salesforce.com(baseurl)>/services/data/vXX.X/composite/graph
Hi,
Here we are going to learn
How to do two composite graph requests each create an Account and then create related records:
Endpoint Url:
Hi,
Here we are going to learn what is Composite Graph API and how it works.
What is Composite Graph API:
Hi,
Let's see the following code how it handles when user doesn’t have permission to insert the Account__c field, which is a lookup from MyCustomObject__c to Account.
// Account__c is a lookup from MyCustomObject__c to Account
@isTest
public class TestCustomObjectLookupStripped {
@isTest static void caseCustomObjectStripped() {
Account a = new Account(Name='foo');
insert a;
List<MyCustomObject__c> records = new List<MyCustomObject__c>{
new MyCustomObject__c(Name='Custom0', Account__c=a.id)
};
insert records;
records = [SELECT Id, Account__c FROM MyCustomObject__c];
SObjectAccessDecision securityDecision = Security.stripInaccessible
(AccessType.READABLE, records);
// Verify stripped records
System.assertEquals(1, securityDecision.getRecords().size());
for (SObject strippedRecord : securityDecision.getRecords()) {
System.debug('Id should be set as Id fields are ignored: ' +
strippedRecord.isSet('Id')); // prints true
System.debug('Lookup field FLS is not READABLE to running user,
should not be set: ' +
strippedRecord.isSet('Account__c')); // prints false
}
}
}
Reference:
Hi ,
Let's assume we recieved a json string with "Name" and "Annual Revenue" to update on Account.
But user doesn't have permisson to update Annual Revenue on Account object.
Then we can avoid updating Annual Revenue on Account object as shown below.
String jsonInput =
'[' +
'{' +
'"Name": "InGen",' +
'"AnnualRevenue": "100"' +
'},' +
'{' +
'"Name": "Octan"' +
'}' +
']';
List<Account> accounts = (List<Account>)JSON.deserializeStrict(jsonInput, List<Account>.class);
SObjectAccessDecision securityDecision = Security.stripInaccessible(
AccessType.UPDATABLE, accounts);
// Secure update
update securityDecision.getRecords(); // Doesn’t update AnnualRevenue field
System.debug(String.join(securityDecision.getRemovedFields().get('Account'), ', ')); // Prints "AnnualRevenue"
System.debug(String.join(securityDecision.getModifiedIndexes(), ', ')); // Prints "0”
Hi,
Let's take a scenario that
The user who doesn’t have permission to create Rating for an Account can still create an Account.
Her the method "Security.stripInaccessible" ensures that no Rating is set and doesn’t throw an exception.
Eg:
List<Account> newAccounts = new List<Account>();
Account a = new Account(Name='Acme Corporation');
Account b = new Account(Name='Blaze Comics', Rating=’Warm’);
newAccounts.add(a);
newAccounts.add(b);
SObjectAccessDecision securityDecision = Security.stripInaccessible(
AccessType.CREATABLE, newAccounts);
// No exceptions are thrown and no rating is set
insert securityDecision.getRecords();
System.debug(securityDecision.getRemovedFields().get('Account')); // Prints "Rating"
System.debug(securityDecision.getModifiedIndexes()); // Prints "1"
Hi,
Here we are going to learn how to remove inaccessible fields from the subquery:
Scenario:
Remove the "Phone" field on Contact Object that the user doesn’t have read permission.
Code Snippet:
List<Account> accountsWithContacts =
[SELECT Id, Name, Phone,
(SELECT Id, LastName, Phone FROM Account.Contacts)
FROM Account];
// Strip fields that are not readable
SObjectAccessDecision decision = Security.stripInaccessible(
AccessType.READABLE,
accountsWithContacts);
// Print stripped records
for (Integer i = 0; i < accountsWithContacts.size(); i++)
{
System.debug('Insecure record access: '+accountsWithContacts[i]);
System.debug('Secure record access: '+decision.getRecords()[i]);
}
// Print modified indexes
System.debug('Records modified by stripInaccessible: '+decision.getModifiedIndexes());
// Print removed fields
System.debug('Fields removed by stripInaccessible: '+decision.getRemovedFields());
Hi,
Here we are going to learn how to remove inaccessible fields from the query:
Let's take a scenario
A display table for campaign data must always show the BudgetedCost. The ActualCost must be shown only to users who have permission to read that field.
Code Snippet:
SObjectAccessDecision securityDecision =
Security.stripInaccessible(AccessType.READABLE,
[SELECT Name, BudgetedCost, ActualCost FROM Campaign];
);
// Construct the output table
if (securityDecision.getRemovedFields().get('Campaign').contains('ActualCost')) {
for (Campaign c : securityDecision.getRecords()) {
//System.debug Output: Name, BudgetedCost
}
} else {
for (Campaign c : securityDecision.getRecords()) {
//System.debug Output: Name, BudgetedCost, ActualCost
}
}
Reference:
Hi ,
Here we are going to learn about Security.StripInaccessible method.
How does it work?
Hi,
Here we learn how can we use Safe Navigation Operator:
We Use the safe navigation operator (?.) to replace explicit, sequential checks for null references.
This operator short-circuits expressions that attempt to operate on a null value and returns null instead of throwing a NullPointerException.
If the left-hand-side of the chain expression evaluates to null, the right-hand-side is not evaluated. Use the safe navigation operator (?.) in method, variable, and property chaining. The part of the expression that is not evaluated can include variable references, method references, or array expressions.
This example first evaluates a, and returns null if a is null. Otherwise, the return value is a.b.
a?.b // Evaluates to: a == null ? null : a.b
This example indicates that the type of the expression is the same whether the safe navigation operator is used in the expression or not.
Integer x = anObject?.anIntegerField; // The expression is of type Integer because the field is of type Integer
This example shows a single statement replacing a block of code that checks for nulls.
// Previous code checking for nulls
String profileUrl = null;
if (user.getProfileUrl() != null) {
profileUrl = user.getProfileUrl().toExternalForm();
}
This example shows a single-row SOQL query using the safe navigation operator.
// Previous code checking for nulls
results = [SELECT Name FROM Account WHERE Id = :accId];
if (results.size() == 0) { // Account was deleted
return null;
}
return results[0].Name;
// New code using the safe navigation operator
return [SELECT Name FROM Account WHERE Id = :accId]?.Name;
References:
Hi,
Here we are going to learn how can we include Lightning Experience theme and Branding set in package.xml for retrieving and deploying the same.
Reference:
https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_brandingset.htm
Hi ,
Here we are going learn how we can Convert Source format to Metadata Format and Deploy with the help of SFDX commands.
We can do this via command prompt or vs code terminal after opening the project.
Let's look into following simple steps:
Hi,
When we develop Lightning web components we can customize a component’s behavior based on whether the current user has specific permission.
To check whether a user has a permission, import Salesforce permissions from the @salesforce/userPermission and @salesforce/customPermission scoped modules and evaluate whether it’s true or undefined. Then if the user has the permission, the component can take a specific action.
Custom permissions can include a namespace. Orgs use namespaces as unique identifiers for their own customization and packages. If the custom permission was installed from a managed package, prepend the namespace followed by __ to the permission name.
Standard Permission Example:
import hasPermission from '@salesforce/userPermission/StandardPermissionName';
Custom Permission Examples:
import hasPermission from '@salesforce/customPermission/CustomPermissionName';
import hasPermission from '@salesforce/customPermission/namespace__CustomPermissionName';
The name of the static reference is your choice. These examples chose the format hasPermission to indicate that the reference contains a Boolean.
Reference:
https://trailhead.salesforce.com/content/learn/modules/platform-developer-i-certification-maintenance-winter-21/learn-whats-new-in-lightning-web-components-and-visualforce
Hi,
Here we are going to learn how can we prepare test data for Content Document.
Let's take a scenario that when a File is inserted under an Account record then "Count of files" should be calculated. (Solution: Apex Trigger on ContentDocumentLink)
Then the following test class will be useful for testing the above scenario.
To insert Content Document Link object record we have to insert ContentVersion first then retrieve the
ContentDocument and then insert ContentDocumentLink object record.
@isTest
private class ContentDocumentLinkActionsTest {
testmethod static void insertContentDocumentTest(){
Account actObj = new Account();
actObj.Name = 'Salesforce Techbook';
insert actObj;
//start insert a filer under Account
ContentVersion content=new ContentVersion();
content.Title='Header_Picture1';
content.PathOnClient='/' + content.Title + '.jpg';
Blob bodyBlob=Blob.valueOf('Unit Test ContentVersion Body');
content.VersionData=bodyBlob;
content.origin = 'H';
insert content;
List<ContentDocument> documentsObj = [SELECT Id, Title, LatestPublishedVersionId FROM ContentDocument
where LatestPublishedVersionId=:content.Id];
ContentDocumentLink contentlink=new ContentDocumentLink();
contentlink.LinkedEntityId=actObj.id;
contentlink.contentdocumentid=[select contentdocumentid from contentversion where id =: content.id].contentdocumentid;
contentlink.ShareType = 'V';
Test.startTest();
insert contentlink;
Test.stopTest();
}
}
Hi,
Here let's see what is Granular Locking Feature and its advantages.
Granular locking can help customers who experience locking issues("org" locks or lock errors). Without this feature, our code locks the entire table that keeps track of people’s membership in various groups.
This means that any two administrative operations that change roles, public groups, or territories will conflict if they happen simultaneously. With granular locking, the code first analyses each operation and locks only the portions of the table touched by each.
This makes it much less likely that any two group membership operations will conflict, and so customers who are using this feature will experience many fewer locks. In most cases, customers will find that with granular locking they can perform manual administration while automated update processes are running, and introduce some degree of multi-threading into integration code and other automated processes.
By default, granular locking is enabled, which allows some group maintenance operations to proceed simultaneously if there is no hierarchical or other relationship between the roles or groups involved in the updates. Administrators can adjust their maintenance processes and integration code to take advantage of this limited concurrency to process large-scale updates faster, all while still avoiding locking errors.
How can I tell if I should use granular locking?
Customers who only occasionally receive an error message indicating that they have encountered a group membership lock are probably not good candidates for this feature. Customers should consider using this feature only if they experience frequent and persistent locking that severely restricts their ability to manage both manual and automated updates at the same time, or severely degrades the throughput of integrations or other automated group maintenance operations.
Advantages:
Reference:
https://help.salesforce.com/articleView?id=000325942&type=1&mode=1
https://developer.salesforce.com/docs/atlas.en-us.draes.meta/draes/draes_group_membership_locking.htm
https://developer.salesforce.com/docs/atlas.en-us.210.0.draes.meta/draes/draes_tools_granular_locking.htm
Hi,
We are going to learn what is SavePoint & Rollback along with limitations.
savePoint:
A point in the request that specifies the state of the database at that time. Any DML statement that occurs after the savepoint can be discarded, and the database can be restored to the same condition it was in at the time you generated the savepoint.
The savePoint statement helps to identify a point in a transaction to which you can later roll back.
rollback:
It helps to roll back the transaction based on savePoint.
Eg:
Account a = new Account(Name = 'xxx');
insert a;
System.assertEquals(null, [SELECT AccountNumber FROM Account WHERE Id = :a.Id].
AccountNumber);
// Create a savepoint while AccountNumber is null
Savepoint sp = Database.setSavepoint();
//Change the account number
a.AccountNumber = '123';
update a;
System.assertEquals('123', [SELECT AccountNumber FROM Account WHERE Id = :a.Id].
AccountNumber);
// Rollback to the previous null value
Database.rollback(sp);
System.assertEquals(null, [SELECT AccountNumber FROM Account WHERE Id = :a.Id].
AccountNumber);
Limitations apply to generating savepoint variables and rolling back the database:
Reference:
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_transaction_control.htm
Hi,
Let's have a look into a few points below to Tune Data Relationships and updates for Performance.
We always need to understand the performance characteristics of the various maintenance operations that we are performing and always test substantial data uploads and changes to object relationships in a sandbox environment so we know what to expect.
Hi,
Here we are going to learn about Implicit Sharing.
The sharing capabilities of the Lightning Platform include a wide variety of features that administrators can use to explicitly grant access to data for individuals and groups.
In addition to these more familiar functions, there are a number of sharing behaviors that are built into Salesforce applications. This kind of sharing is called implicit because it’s not configured by administrators; it’s defined and maintained by the system to support collaboration among members of sales teams, customer service representatives, and clients or customers.
Let's have a look into the following table which describes the different kinds of implicit sharing built into Salesforce applications and the record access that each kind provides.
Type of Sharing | Provides | Details |
---|---|---|
Parent | Read-only access to the parent account for a user with access to a child record |
|
Child | Access to child records for the owner of the parent account |
|
Portal | Access to portal account and all associated contacts for all portal users under that account | Shared to the lowest role under the portal account |
High Volume1 | Access to data owned by high volume users associated with a sharing set for users member of the sharing set's access group | All members of the sharing set access group gain access to every record owned by every high volume user associated with that sharing set |
High Volume Parent | Read only access to the parent account of records shared through a sharing set's access group for users member of the group | Maintains the ability to see the parent account when users are given access to account children owned by high volume users |
Hi,
Let's learn about Parent-Child Data Skew.
A common configuration that can lead to poor performance is the association of a large number of child records (10,000 or more) with a single parent account.
Eg: A customer can have tens or hundreds of thousands of contacts generated by marketing campaigns or purchased from mailing lists—without any association to formal business accounts. If contact is required to have an associated account, what should an administrator do? It might be convenient to park all those unallocated contacts under a single dummy account until their real business value and relationship can be determined.
While this option seems reasonable, this kind of parent-child data skew can cause serious performance problems in the maintenance of implicit sharing.
Hi,
Let's see what is ownership Data Skew.
We have different types of Data Skews.
Eg:
A customer can assign all of his or her unassigned leads to a dummy user. This practice might seem like a convenient way to park unused data, but it can cause performance issues if those users are moved around the hierarchy, or if they are moved into or out of a role or group that is the source group for a sharing rule. In both cases, Salesforce must adjust a very large number of entries in the sharing tables, which can lead to a long-running recalculation of access rights.
If we do have a compelling reason for assigning ownership to a small number of users, we can minimize possible performance impacts by not assigning the user(s) to a role.
Hi ,
When a Visualforce page is loaded, the fields accessible to the page are based on the fields referenced in the Visualforce markup. This method adds a reference to each field specified in "fieldNames" so that the controller can explicitly access those fields as well.
Here "fieldNames" data type is List<String> .
The strings in fieldNames can either be the API name of a field, such as AccountId, or they can be explicit relationships to fields, such as something__r.myField__c.
Usage:
This method should be called before a record has been loaded—typically, it's called by the controller's constructor. If this method is called outside of the constructor, you must use the reset() method before calling addFields().
This method is only for controllers used by dynamicVisualforce bindings.
Sample Example:
public AccountController(ApexPages.StandardController stdController){
this.controller = stdController;
List<String> fieldNamesList = new List<String>{Type,Industry};
stdController.addFields(fieldNamesList);
}
Reference:
https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/apex_ApexPages_StandardController_addFields.htm
Hi,
Let's have a look at how the triggers behave written on "ContentDocument and ContentDocumentLink" objects in Salesforce Classic and Salesforce Lightning.
Here we are going to discuss what is going to happen when we write a trigger for the "delete" event on the above objects.
In Classic:
ContentDocument triggers do not fire, as Salesforce only deletes the associated ContentDocumentLink record, not the ContentDocument record.
In Lightning Experience:
both the ContentDocument and related ContentDocumentLink records are deleted, and by design Salesforce only fires the trigger on ContentDocument, not the trigger on ContentDocumentLink.
This is working as designed and can be verified by following below steps:
1. Create two "before delete" triggers: one on ContentDocument, and the other on ContenDocumentLink objects.
2. Place a "system.debug" statement in each which could be verified in the Debug logs.
3. Now upload 2 files to any Object record under 'Files' related list. Once done, you can observe both the uploaded documents under the 'Files' tab.
4. Execute the below queries in the Developer Console.
SELECT Id, LinkedEntityId, ContentDocumentId FROM ContentDocumentLink WHERE LinkedEntityId=<<Id og the document>>
2 records will be returned
SELECT Id, Title FROM ContentDocument WHERE Id=<<ContentDocumentId from the above query>>
2 rows will be returned
5. Set up the Debug logs
IN CLASSIC:
Delete one of the uploaded files, by clicking on the 'Del' link besides the document under 'Files' related list.
OBSERVATION:
In Debug logs you will see that only the ContentDocumentLinkTrigger has got fired and the Debug statement present in that Trigger will get displayed.
The document you have deleted will be available under the 'Files' tab
On executing the above 2 queries you will observe that only 1 row is returned for the 1st query and 2 rows for the second query. i.e. Only the ContentDocumentLink is getting removed.
IN LIGHTNING:
Open the object record and delete the 2nd uploaded file, by clicking on the 'Del' link besides the document under 'Files' related list.
OBSERVATION:
In Debug logs you will see that only the ContentDocumentTrigger has got fired and the Debug statement present in that Trigger will get displayed.
The document you have deleted will no longer be available under the 'Files' tab
On executing the above 2 queries you will observe that no row is returned for the 1st query and 1 row for the second query (the one related to the 1st document). i.e. Both the ContentDocument and the ContentDocumentLink have got removed.
Note:
We should remember if we are trying to write tirggers on "delete" event on these objects.
This content is from following Salesforce Link.
Reference:
https://help.salesforce.com/articleView?id=000312746&language=en_US&type=1&mode=1
How Does Einstein Article Recommendations Work? Einstein Article Recommendations helps support agents resolve customer cases efficiently by ...