Showing posts with label Calling Future Method. Show all posts
Showing posts with label Calling Future Method. Show all posts

Tuesday, November 20, 2018

Future Method and Mixed DML Errors in Salesforce.com

Future Method and Mixed DML Errors in Salesforce.com

When we perform DML on setup and non-setup sObject simultaneously then mixed dml errors occurs. 

To avoid mixed DML errors
1) Create a method that performs a DML operation on one type of sObject.
2) Create a second method that uses the future annotation to manipulate a second sObject type.

Apex Class

public class MixedDMLFuture {
    public static void useFutureMethod() {
        // First DML operation
        Account a = new Account(Name='Acme');
        insert a;
       
        // This next operation (insert a user with a role)
        // can't be mixed with the previous insert unless
        // it is within a future method.
        // Call future method to insert a user with a role.
        
UtilClass.insertUserWithProfileAndRole('username@abc.com', 'myAlias',
            'emailAddress@abc.com', 'Bill','Business Head', 'CEO');       
    }
}


Apex Future Method

public class UtilClass {
    @future
    public static void insertUserWithProfileAndRole(
        String userNameIs, String aliasIs, String emailAdd, String lastNameIs, String profileName, String roleName) {
        
//Get the profile Id 
        Profile profile = [SELECT Id FROM Profile WHERE Name=:profile];
//Get the role Id
        UserRole role = [SELECT Id FROM UserRole WHERE Name=:role];
        
// Create new user with a non-null user role ID
        User usr = new User(alias = aliasIs, 
            email=emailAdd,
            emailencodingkey='UTF-8', 
            lastname=lastNameIs,
            languagelocalekey='en_US',
            localesidkey='en_US', 
            profileid = profile.Id, 
            userroleid = role.Id,
            timezonesidkey='America/Los_Angeles',
            username=userNameIs);
        insert usr;
    }
}


Apex Test Class
============

Mixed DML Operations in Test Methods :-
The System.runAs() block runs in the current user’s context. It creates a test user with a role and a test account, which is a mixed DML operation.
Using Test.startTest and Test.stopTest to bypass the mixed DML error in a Test Method.

@isTest
private class insertUserWithProfileAndRoleTest{

    static testMethod void createTestUser(){

        Profile pro = [Select Id From Profile Where Name = 'System Administrator'];

        //Create setup sObject records (User)
        User usr = new User();
        usr.FirstName = 'First';
        usr.LastName = 'Last';
        usr.Email = 'first@test.com';
        usr.Username = 'astest@test.com';
        usr.Alias = 'first';
        usr.ProfileId = pro.Id;
        usr.TimeZoneSidKey = 'America/Denver';
        usr.LocaleSidKey = 'en_US';
        usr.EmailEncodingKey = 'UTF-8';
        usr.LanguageLocaleKey = 'en_US';
        insert usr;

        system.debug('usr is ' + usr);

        System.runas(usr){

            //Create non-setup records & run tests here
        }
    }
}












Asynchronous Apex: Future Method in Salesforce.com

Future Method

1) Making callouts to external web services. 
i.e. When we are making callouts to external web services from a trigger or after performing a DML operation, we must use a future or queueable method.

2) Process we want to run in its separate thread in the back-end.
i.e. When we are working on some sort of resource consuming calculation or processing of records.

3) Isolating DML operations on different types of sObject.
i.e. When we are performing DML on setup and non-setup sObject types, it isolates DML to prevent the "Mixed DML Errors".


Future Method Syntax:
global class FutureClass {
     @future
     public static void futureMethod(List<Id> recordIds) {
     List<Account> accounts = [Select Id, Name from Account Where Id IN :recordIds];
     // process account records to do awesome stuff
     }
}


Future Method Considerations

1) Future methods must be static methods and return a void.

2) Parameters must be primitive data types, arrays of primitive data types, or collections of primitive data types.
Note:- Future methods can’t take standard or custom objects as arguments.

3) Common pattern is to pass a List<record IDs> that you want to process asynchronously.

4) Future methods can’t be used in Visualforce controllers in getMethod(), setMethod(), nor in the constructor.

5) You can’t call a future method from a future method.

6) You can not invoke a trigger that calls a future method while running a future method.

7) The getContent() and getContentAsPDF() methods can’t be used in future method.

8) You’re limited to 50 future calls per Apex invocation.

9) To test future methods, enclose your test code between the test.startTest() and test.stopTest() test methods.


Validation in flow input text field in sfdc: Maximum 255 characters limit

The input text field validate in sfdc flow behaves opposite of the generic sfdc validation rule.  Here the validation formula is evaluating ...