Category Archives: Salesforce

sObjects That Don’t Support DML Operations

Following standard objects don’t support DML operations, but it supports SOQL query.

  • AccountTerritoryAssignmentRule
  • AccountTerritoryAssignmentRuleItem
  • ApexComponent
  • ApexPage
  • BusinessHours
  • BusinessProcess
  • CategoryNode
  • CurrencyType
  • DatedConversionRate
  • NetworkMember (allows update only)
  • ProcessInstance
  • Profile
  • RecordType
  • SelfServiceUser
  • StaticResource
  • Territory2
  • UserAccountTeamMember
  • UserTerritory
  • WebLink

Set Approval Process Lock And Unlock Records Using Apex Code

Sometimes we have faced business requirement to Lock or Unlock records in Salesforce. We can use apex lock() and unlock() methods in the System.Approval namespace to lock and unlock records by passing in record IDs or sObjects.

To enable this feature, go to Setup | Search Automation Settings in the Quick Find box | click on Automation Settings. Then, select Enable record locking and unlocking in Apex.

Lock Record Example:

//Get records to lock
List<case> caseList = [SELECT Id From Case LIMIT 10];
//Lock records
List<Approval.LockResult> lrList = Approval.lock(caseList, false);

// Iterate through each returned result
for(Approval.LockResult lr : lrList) {
    if (lr.isSuccess()) {
        //Operation was successful, so get the ID of the record that was processed
        System.debug('Successfully locked account with ID: ' + lr.getId());
    }
    else {
        //Operation failed, so get all errors                
        for(Database.Error err : lr.getErrors()) {
            System.debug('The following error has occurred.');                    
            System.debug(err.getStatusCode() + ': ' + err.getMessage());
            System.debug('Case fields that affected this error: ' + err.getFields());
        }
    }
}

Unlock Record Example:

//Get records to unlock
List<case> caseList = [SELECT Id From Case LIMIT 10];
//Check locked records
List<case> caseLockList = new List<Case>();
for(Case c :caseList){
    if(Approval.isLocked(c.id)){
        caseLockList.add(c);
    }
}
//Unlock record
if(!caseLockList.isEmpty()){
    //Unlock records
    List<Approval.UnlockResult> ulrList = Approval.unlock(caseLockList, false);
    
    // Iterate through each returned result
    for(Approval.UnlockResult  ulr : ulrList) {
        if (ulr.isSuccess()) {
            //Operation was successful, so get the ID of the record that was processed
            System.debug('Successfully locked account with ID: ' + ulr.getId());
        }
        else {
            //Operation failed, so get all errors                
            for(Database.Error err : ulr.getErrors()) {
                System.debug('The following error has occurred.');                    
                System.debug(err.getStatusCode() + ': ' + err.getMessage());
                System.debug('Case fields that affected this error: ' + err.getFields());
            }
        }
    }
}

Send Email With Document As An Attachment Using Apex In Salesforce

Sample Code Approach 1:

//Get your document from document Object
Document doc = [Select Id, Name, Body, ContentType, DeveloperName, Type From Document Where DeveloperName = 'Your_Doucment_DeveloperName'];

//Create Email file attachment from document
Messaging.EmailFileAttachment attach = new Messaging.EmailFileAttachment();
attach.setContentType(doc.ContentType);
attach.setFileName(doc.DeveloperName+'.'+doc.Type);
attach.setInline(false);
attach.Body = doc.Body;

//Apex Single email message
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setUseSignature(false);
mail.setToAddresses(new String[] { 'itzbiswajeet@gmail.com' });//Set To Email Address
mail.setSubject('Test Email With Attachment');//Set Subject
mail.setHtmlBody('Please find the attachment.');//Set HTML Body
mail.setFileAttachments(new Messaging.EmailFileAttachment[] { attach });//Set File Attachment
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });//Send Email

Sample Code Approach 2:

//Get your document from document Object
Document doc = [Select Id, Name, Body, ContentType, DeveloperName, Type From Document Where DeveloperName = 'Your_Doucment_DeveloperName'];

//Apex Single email message
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setUseSignature(false);
mail.setToAddresses(new String[] { 'itzbiswajeet@gmail.com' });//Set To Email Address
mail.setSubject('Test Email With Attachment');//Set Subject
mail.setHtmlBody('Please find the attachment.');//Set HTML Body
mail.setDocumentAttachments(new Id[]{doc.Id});//Set Document Attachment
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });//Send Email

Platform Cache In Salesforce

What is Cache?
Cache is a temporary data storing technique. We use Cache to store static data, that is being used frequently in our application for faster performance and better reliability.

What is Platform Cache?
Platform Cache is a memory layer that stores Salesforce session and org data for later access. When we use Platform Cache, the application can run faster because they store reusable data in memory. Application can quickly access this data; they don’t need to duplicate calculations and requests to the database on subsequent transactions. The Platform Cache is like the RAM for the cloud application.

There are two types of Platform Cache:

Session Cache: It stores data for individual user sessions and lives alongside a user session. The maximum life of a session is 8 hours. Session cache expires when its specified time-to-live is reached or when the session expires after eight hours, whichever comes first.

Org Cache: It stores data that any user in an org reuses. Unlike session cache, org cache is accessible across sessions, requests, and org users and profiles. Org cache expires when its specified time-to-live is reached.

When can we use Platform Cache?
We can use Platform Cache, when we want to store temporary data to use in code, but do not want to save it in database. Using cached data improves the performance of the application and is faster than performing SOQL queries repetitively, making multiple API calls, or computing complex calculations.

Platform Cache Considerations:

  • Cache isn’t persisted. There’s no guarantee against data loss.
  • Some or all cache is invalidated when you modify an Apex class in your org.
  • Data in the cache isn’t encrypted.
  • Org cache supports concurrent reads and writes across multiple simultaneous Apex transactions.
  • Session cache doesn’t support asynchronous Apex. Like we can’t use future methods or batch Apex with session cache.
  • The session cache can store values up to eight hours and the org cache can store values up to 48 hours.

Platform Cache Limits:

Cache Allocations by Edition:

  • Developer Edition (0 MB by Default, but can get 10 MB as a trial).
  • Enterprise Edition (10 MB by default)
  • Unlimited Edition (30 MB by default)
  • Performance Edition (30 MB by default)

Session Cache Limits:

  • Maximum size of a single cached item for put() methods (100 KB)
  • Maximum local cache size for a partition, per-request (500 KB)
  • Minimum developer-assigned time-to-live 300 seconds (5 minutes)
  • Maximum developer-assigned time-to-live 28,800 seconds (8 hours)
  • Maximum session cache time-to-live 28,800 seconds (8 hours)

Org Cache Limits:

  • Maximum size of a single cached item for put() methods (100 KB)
  • Maximum local cache size for a partition, per-request (1,000 KB)
  • Minimum developer-assigned time-to-live 300 seconds (5 minutes)
  • Maximum developer-assigned time-to-live 172,800 seconds (48 hours)
  • Default org cache time-to-live 86,400 seconds (24 hours)

Create Partition of Platform Cache:
Go to Setup | Search “Platform Cache” in Quick Find Box | Click Platform Cache

In developer edition, it is 0 MB space default. But we can get 10 MB on click of “Request Trial Capacity” button.

Now Click on “New Platform Cache Partition” to create Partition.

Each partition has one session cache and one org cache segment and you can allocate separate capacity to each segment. Session cache can be used to store data for individual user sessions, and org cache is for data that any users in an org can access.


Note: We cannot delete default Partition. If you want to delete partition, you have to uncheck the default partition option.

Put and retrieve data using Platform cache:
To call Partition in apex code we use namespace.partitionName. local as namespace can be used in both scenario if you have namespace enabled or not enable in your org. In below example I’m using “myPartition” partition.

Store and Retrieve Values from the Session Cache:

Session Cache in Apex Class:

//Add a value to the cache
Integer cartValue = 22;
Cache.Session.put('local.myPartition.CartValue', cartValue);
if (Cache.Session.contains('local.myPartition.CartValue')) {
    Integer cachedCartValue = (Integer)Cache.Session.get('local.myPartition.CartValue');
}

To refer to the default partition and the namespace of the invoking class, we can omit the namespace.partition prefix and specify the key name.

//Use of default partition without namespace and partition
Cache.Session.put('CartValue', 22);
if (Cache.Session.contains('CartValue')) {
    Integer cachedCartValue = (DateTime)Cache.Session.get('CartValue');
}

Session Cache in Visualforce Page:

<apex:outputText value="{!$Cache.Session.local.myPartition.CartValue}"/>

Store and Retrieve Values from the Org Cache:

Org Cache in Apex Class:

//Add a value to the cache
Integer cartValue = 22;
Cache.Org.put('local.myPartition.CartValue', cartValue);
if (Cache.Org.contains('local.myPartition.CartValue')) {
    Integer cachedCartValue = (Integer)Cache.Org.get('local.myPartition.CartValue');
}
//Use of default partition without namespace and partition
Cache.Org.put('CartValue', 22);
if (Cache.Org.contains('CartValue')) {
    Integer cachedCartValue = (DateTime)Cache.Org.get('CartValue');
}

Org Cache in Visualforce Page:

<apex:outputText value="{!$Cache.Org.local.myPartition.CartValue}"/>