Sunday, May 13, 2018

‘With Sharing ‘/ ‘Without Sharing’ In Salesforce.



Salesforce keywords just make wonders and ‘With Sharing ‘/ ‘Without Sharing’ keyword is one of them and sometimes we are oblivious about how they work internally.

Let’s try to understand each.

‘With Sharing’:       
This keyword can be used on Apex classes, like public With Sharing classcontactMasterTriggerHandler{ }.

What does it do??
Though apex always executes in System Context, but ‘With Sharing’ keyword only enforces ‘Record level security’ , ‘User Permissions’ and ‘Profile permissions’ of the Context User doing some operation, but doesn't enforce Field level security. 

For an instance if a with sharing class is updating a list of an object and context user doesn't have Edit access to that object, then it will throw error of 'Insufficient access/privileges' ,on the other hand it ignores the FLS, in case user doesn't even have edit access to field, won't throw any error and updates successfully.
To understand this point, let's take a look at the example below: 

Let’s take an instance

There is a trigger on Contact using a trigger handler with a keyword ‘With Sharing’, and in 
After Update of Contact it updates Account’s Rating field based upon some conditions.
Here's OWD of Account is private and since Contact OWD is governed 'by parent' so it is also Private.

User has no access to all other Account record excepts the ones he/she created (due to OWD as Private and no other sharing is done) and doesn’t have FLS to Rating field of Account (This is to be updated in given code below)

How should it behave for such scenario having 'With Sharing' on Trigger handler Apex: 

Let's take a look at the code: 



·       OWD as Private and No FLS access:
It will not pickup account record it doesn't access to, so only records user has access are picked and updated, but doesn’t throw any error.

·       OWD as Public read/Write and No FLS access:
It will pickup all the account records that SOQL is returning but despite of having no FLS access, doesn’t throw any error saying insufficient access to the field.



2nd Instance: 
       Let's say there is a Visual force page having apex controller as 'With Sharing' behaves in the same way as explained in above example.
But visibility of fields on a VF page totally depends on user who's opening the page, be it with or without sharing keyword with Apex controller.

Without Sharing’:
             When no keyword is given with Apex class name, it is by default 'Without Sharing' , however you can also use the without sharing keywords to ensure that Apex scripts do not enforce the sharing rules of the running user. 


Without Sharing apex executes in System context and hence apex code has access to all objects and fields— object permissions, field-level security, sharing rules aren’t applied for the current user. This is to ensure that code won’t fail to run because of hidden fields or objects for user. 

Key Points about 'With Sharing' / 'Without Sharing' 
  • If the class is called by another class that has sharing enforced, then sharing is enforced for the called class.
  • ExecuteAnonymous always executes using the full permissions of the current user (including sharing settings).
  • The sharing setting of the class where the method is defined is applied, not of the class where the method is called. For example, if a method is defined in a class declared with with sharing is called by a class declared with without sharing, the method will execute with sharing rules enforced.

Sunday, April 29, 2018

"System.QueryException: Non-selective query against large object type" is thrown.

If you're running a trigger on objects that have more than 200,000 records, this error may occur, "System.QueryException: Non-selective query against large object type."


How to resolve:

  •    Make sure the SOQL is selective by using good filters like 'IN' with a set/list of records like where Id in :optyIdSet, that ensures that query will not return all the records exists on  object.
  •    Right operand of where clause should not be null or blank, for example: where Name in :setOfNames; and setOfNames must be initialized or should not be blank.
  •     Before putting the query in apex, make sure SOQL is not breaking governer limit. One may check governer limit of SOQL by using a simple debug in apex System.debug('LimitOfSOQLRows:'+Limits.getLimitQueryRows());
  •    Avoid using OR conditions in SOQL on objects having more than 200,000 records. Prefer using AND condition, but if need to use it you may use that in loop using If conditions.
  •    Put your query in Query plan tool of Salesforce Developer console to ensure that it is  selective and ready to be used in apex.
  •    Avoid using negative operator such as NOT EQUAL TO ( !=), NOT CONTAINS, and NOT STARTS WITH in SOQL to get records.
  •    Do not use a formula field for filtering in SOQL.
  •    Making a field indexed also helps resolving this error, but first try all above steps to see if it  resolves, else you may make a field indexed. By default, Lookup, Master Detail and external     id fields are indexed, For custom indexing, kindly contact Salesforce.com support.


Monday, April 16, 2018

Lightning Page could not be loaded because it includes too many formula fields with complex formulas, or too many custom fields OR Cannot load a page layout with more than 254 fields in lightning interface..!!



This is quite annoying to have this error while opening a record detail page in salesforce lightning.
As of now this is available in known issues of Salesforce lightning but does not have a great fix but to reduce the number of lookup and formula fields from the layout.

    Workaround:
Page layouts should be reduced in the following areas:
1) Reduce Lookup fields to below 35
2) Reduce Formula fields to below 30-40
3) Consider reducing overall fields below 300 (less impactful)

Click on the Salesforce Idea to Upvote. Idea to Upvote

‘With Sharing ‘/ ‘Without Sharing’ In Salesforce.

Salesforce keywords just make wonders and ‘With Sharing ‘/ ‘Without Sharing’ keyword is one of them and sometimes we are oblivious abo...