Issue Passing Data from Parent to Child Process via BeanShell (Multiple Processes)

Confluence User - 10 Feb, 2025

I am implementing a workflow where multiple child processes need to be started dynamically from a parent process using BeanShell scripting. Since we need to start multiple process instances, we are using the processStart method instead of relying on form-based initiation. However, we are facing an issue where the child process starts successfully, but the form mapped at the start point remains empty, even though we are passing variables correctly via variableMap.

Implementation Details:

We referred to the following example from Joget’s documentation:

Map variableMap = new HashMap();
variableMap.put("status", row.getProperty("purpose"));

// Start a new process instance with data from each row
// processStart(String processDefId, String processId, Map<String, String> variables, String startProcUsername, String parentProcessId, boolean startManually)
workflowManager.processStart("expenseclaim:latest:process1", null, variableMap, null, row.getProperty("id"), false);

This is our implementation:

Map variableMap = new HashMap();
variableMap.put("annual_plan_title", rs.getString("id"));
variableMap.put("annual_plan_id", rs.getString("id"));

// Start a new process for each row
workflowManager.processStart("Omancpa:29:price_ob_child", null, variableMap, null, processId, false);

Issue:

  • The child process starts, but the form data remains empty.
  • The form is mapped at the start point, and the IDs being passed match.
  • Despite passing variables through variableMap, the child process does not receive the expected data.
  • We need to ensure that multiple child processes start correctly with the necessary form data.

Questions:

  1. What is the correct way to pass form data when starting a process via BeanShell?
  2. Is there any additional configuration required for the child process to accept variables?
  3. Are there any known limitations or alternative methods to ensure that multiple child processes receive the required data?

Looking forward to your responses.

process;beanshell;mulltiprocess

5


10 Feb, 2025
confluenceUser
confluenceUser

Hi Uzair,  Can you tell us what is the processId you are passing in the below line? it should be the primary key of the form data table you are trying to use in the process. 


workflowManager.processStart("Omancpa:29:price_ob_child", null, variableMap, null, processId, false); 


if possible, try sharing the full code with screenshots to help you better. 


11 Feb, 2025
confluenceUser
confluenceUser

Hi,

i am passing the primary key of the parent form but not the primary key of the child form which i am using in Start of child process

this is the code  
       // Process each row by passing the necessary data
        try {
            String processId = rs.getString("id"); // Assuming `id` column is used for the process ID
            String status = rs.getString("c_annual_plan_title"); // Example: Modify based on your requirements
 
            Map variableMap = new HashMap();
            variableMap.put("annual_plan_title",  rs.getString("id"));
             variableMap.put("annual_plan_id", rs.getString("id"));
 
            // Start a new process for each row
            workflowManager.processStart("Omancpa:29:price_ob_child", null, null, null, processId, false);
 
            // Debugging: Log the values to confirm the process start
            System.out.println("Process started for Plan ID: " + processId);
        } catch (Exception e) {
            e.printStackTrace();
        }

11 Feb, 2025
confluenceUser
confluenceUser

Hi Uzair, to ensure child form data is accessible, make sure to pass the child form's primary key when initiating child processes. This key acts as a crucial link, allowing the child process to retrieve and utilize its associated form data effectively


workflowManager.processStart("Omancpa:29:price_ob_child", null, null, null, processId, false); // The processId here should be the primary key of the child form record. 



For reference, see this sample app demonstrating a similar use case with parent-child process relationships and data passing. please feel free to ask for clarification.

APP_service_desk-2-20250211045739.jwa


11 Feb, 2025
confluenceUser
confluenceUser



Bean Shell tool Code (Parent)


import org.joget.apps.app.service.AppUtil;

import org.joget.plugin.base.PluginManager;

import org.joget.workflow.model.service.WorkflowManager;

import javax.sql.DataSource;

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import org.json.JSONObject;




DataSource ds = (DataSource) AppUtil.getApplicationContext().getBean("setupDataSource");

Connection conn = null;

PreparedStatement ps = null;

ResultSet rs = null;

JSONObject rowData = new JSONObject();




String tableName = "app_fd_base_annual";

String planId = "b207aef3-03fb-486d-a8a6-9442c452b1d9";  // Modify this as needed




// Workflow Manager to start processes

WorkflowManager workflowManager = (WorkflowManager) AppUtil.getApplicationContext().getBean("workflowManager");




try {

    conn = ds.getConnection();

    // Query to fetch the data

    String sql = "SELECT id, createdBy, c_annual_plan_title, c_sub_repeat FROM " + tableName + " WHERE id = ?";

    ps = conn.prepareStatement(sql);

    ps.setString(1, planId);  // Set the value for the ID

    rs = ps.executeQuery();




    // Iterate over the result set

    while (rs.next()) {

        int columnCount = rs.getMetaData().getColumnCount();


        // Extract each column and store it in a JSON object

        for (int i = 1; i <= columnCount; i++) {

            String columnName = rs.getMetaData().getColumnName(i);

            Object columnValue = rs.getObject(i);


            // Add column data to the JSON object

            rowData.put(columnName, columnValue);

        }


        // Process each row by passing the necessary data

     try {

            String processId = planId; // Assuming `id` column is used for the process ID

            String status = rs.getString("c_annual_plan_title"); // Example: Modify based on your requirements


            Map variableMap = new HashMap();

            variableMap.put("annual_plan_title",  rs.getString("id"));

             variableMap.put("annual_plan_id", rs.getString("id"));


            // Start a new process for each row

            workflowManager.processStart("Omancpa:29:price_ob_child", null,variableMap, null, processId, false);


            // Debugging: Log the values to confirm the process start

            System.out.println("Process started for Plan ID: " + processId);

        } catch (Exception e) {

            e.printStackTrace();

        }


    }

} catch (SQLException e) {

    e.printStackTrace();

} finally {

    // Clean up resources

    try {

        if (rs != null) {

            rs.close();

        }

        if (ps != null) {

            ps.close();

        }

        if (conn != null) {

            conn.close();

        }

    } catch (SQLException e) {

        e.printStackTrace();

    }

}




// Return the JSON data as a string (optional if needed)

return rowData.toString();


Start Child Process Snap 
how can we pass primary key of child form as no entry has been made to that form as it is start of the process

11 Feb, 2025
confluenceUser
confluenceUser

To pass a primary key to a child form when no entry has been made ---- if there's no data, then what kind of data are you trying to pass or have available in the child process in the first place, besides some workflow variables? Specifically, what type of child data needs to be made available? Can you please tell us the usecase you are trying to implement there might be a better approach. 


other approaches you can try: 

Workflow Variables: Use workflow variables to pre-populate fields when rendering the child form. Map these variables to database values first, then default values as a fallback. This approach works best for initial data, but the form will still be largely empty.

Process and Primary Key Linkage: A process is typically linked to a primary key of a table.

If you don't have this primary key at the start:
a) Keep the start empty.
b) Add a new activity right after the start where users can fill the form.
c) In the processStart code, pass null instead of a processId (primary key).


Preset Data Approach: If you need to preset data: Create a new record in the table with relevant child form data. Retrieve the primary key of this new record. Pass this primary key (as processId) to the child process.

RELATED QUESTIONS

Your answer


To answer a question you'll need an account.

Print