How invocable method and bulk behavior in Process Builder work?

  • I am trying to understand how invocable method called from Process builder behaves. I have Process Builder process on Account which has apex action. Apex action needs to be executed for record inserts.

    Below are my questions,

    1. if 10 account records are inserted "at the same time", Process builder process is called 10 times, separately for each record that is being inserted. or only once ?

    2. if process has apex action and if 10 records are inserted at the same time, is the apex action called 10 times separately or only once for all 10 records ?

    3. Process builder calls apex action method which takes ID as the parameter. can I write invocable method that takes ID as the parameter instead of List ? I saw some examples where invocable methods are taking List or List as parameter. Is it possible that apex action invoked from process builder is called for multiple records at the same time ?

    Any insight into process builder working would be very helpful.

    Did you eventually find an answer?

  • You can also create an @InvocableMethod that takes in a List of a custom class. By doing this, you can pass in parameters in the Process Builder

    public with sharing class ActionForProcessBuilder {
    
        @InvocableMethod(label='Do Action')
        public static void doAction(Request[] requests) {
            // Process requests
            // Example: Query parents in bulk
            Map<Id, Parent__c> parents = new Map<Id, Parent__c>();
    
            for(Request request : requests) {
                parents.put(request.parentId, null);
            }
    
            parents = new Map<Id, Parent__c>([
                SELECT Id, Due_Date__c
                FROM Parent__c
                WHERE Id IN :parents.keySet()
            ]);
    
            for(Request request : requests) {
                final Parent__c parent = parents.get(request.parentId);
                if(request.adjustedDueDate != null && parent.Due_Date__c < request.adjustedDueDate) {
                    // Do something
                }
            }
        }
    
        public with sharing class Request {
            @InvocableVariable(label='Record ID' required=true)
            public Id recordId;
    
            @InvocableVariable(label='Parent ID' required=true)
            public Id parentId;
    
            @InvocableVariable(label='Adjusted Due Date' required=false)
            public Date adjustedDueDate;
        }
    }
    
  • The answer for #3 (about parameters as a singleton) is a straight up no:

    There can be at most one input parameter and its data type must be one of the following:

    • A list of a primitive data type or a list of lists of a primitive data type – the generic Object type is not supported.
    • A list of a user-defined type, containing variables of the supported types and with the InvocableVariable annotation. Create a custom global or public Apex class to implement your data type, and make sure your class contains at least one member variable with the invocable variable annotation.

    However, since the Invocable Method requires a list it shows that can be grouped together as they come in. Much the way triggers process.

    On another note (Adding this because this was the question I was looking to solve that led me here):

    • Other annotations can’t be used with the InvocableMethod annotation.

    Therefore, no mixed DML. But you can call an @future method from withing the body of the Invocable method.

    Does not work:

    @future
    @InvocableMethod(label='label' description='description')
    public static void inactivatePortalUsers(List<Id> ids) {
        ...
    }
    

    Will work:

    @InvocableMethod(label='label' description='description')
    public static void inactivatePortalUsers(List<Id> ids) {
        callFuture(ids);
    }
    
    @future
    public static void callFuture(List<Id> ids) {
        //update portal account users to inactive
        //or other mixed dml
    }
    

    Generic SObject and SObject[] are now supported.

  • I did this just yesterday - so haven't tested it thoroughly.....

    But - I passed in the ID from process builder & got it in the method below as a list of IDs

    When I ran in 68 records (batch size 200 with data loader): in the log I got the system debug out 4 times.


    public class InvocableSetQ 
    {
    @InvocableMethod
    public static void SetQ(List<Id> ListID)
    {
        List<Object__c > bidR=[select id , Attribute__c from Object__c where id in :ListID];
        for (Object__c b:bidR ){b.ownerid = c.Queue_ID__c  ;}
        update bidR;
        system.debug('TEST!');
    }
    }
    

    1. If you insert 10 record at once, Process Builder will be called once.
    2. Just like trigger invocation, if you call 10 records, Apex action will be called only once with 10 ids. Apex invocation works same as trigger invocation with batch size of 200. I.e. suppose if I am inserting 410 records at once, invocable method will get called 3 times with batch size of 200, 200, 10 data respectively.

License under CC-BY-SA with attribution


Content dated before 7/24/2021 11:53 AM