Camunda:如何让DMN输出两个变量至BPMN流程上下文?
Let's break down what's happening first: that ENGINE-22002 error is expected behavior. The CollectEntriesDecisionResultMapper you're using is designed exclusively for DMN tables with a single output column—it tries to collect all values for one specific output, so when it sees two outputs (ROUT_TO_DEPT and OUT_CATEGORY), it throws an error.
Here are three practical ways to get those two outputs as independent variables in your BPMN context:
1. Use Multi-Result Mappings in the Business Rule Task (Recommended)
This is the simplest, no-code approach if you're using Camunda 7.x or later:
- Open your Business Rule Task's properties panel
- Navigate to the Result Mappings section (may be labeled "Output Mappings" in older versions)
- Add two separate mappings:
- First Mapping:
- Source:
${decisionResult.singleResult().get('ROUT_TO_DEPT')} - Target:
routToDept(or whatever variable name you want)
- Source:
- Second Mapping:
- Source:
${decisionResult.singleResult().get('OUT_CATEGORY')} - Target:
outCategory
- Source:
- First Mapping:
- Make sure the Decision Result Mapper dropdown is set to
Default(not Collect or Single Result—we're handling the mapping ourselves via expressions) - Save your changes. After the DMN runs,
routToDeptandoutCategorywill be available as standalone variables for all subsequent BPMN steps.
2. Fetch a Single Result Map, Then Split with a Script Task
If your Camunda version doesn't support multi-result mappings, use a script to split the map into individual variables:
- Configure the Business Rule Task:
- Set Result Variable to something like
dmnOutputMap - Set Decision Result Mapper to
Single Result(this converts the winning DMN row into a Java Map)
- Set Result Variable to something like
- Add a Script Task right after the Business Rule Task:
- Choose your preferred script language (Groovy or JavaScript work well):
Groovy Example:
JavaScript Example:// Pull values from the map and set them as independent process variables execution.setVariable('routToDept', dmnOutputMap.get('ROUT_TO_DEPT')) execution.setVariable('outCategory', dmnOutputMap.get('OUT_CATEGORY'))execution.setVariable('routToDept', dmnOutputMap.get('ROUT_TO_DEPT')); execution.setVariable('outCategory', dmnOutputMap.get('OUT_CATEGORY'));
- Choose your preferred script language (Groovy or JavaScript work well):
- Run the process—your two variables will be ready to use after the script task.
3. Custom Decision Result Mapper (For Complex Use Cases)
If you need reusable logic for multiple processes, build a custom mapper:
- Implement Camunda's
DecisionResultMapperinterface:import org.camunda.bpm.engine.impl.dmn.result.DecisionResultMapper; import org.camunda.bpm.dmn.engine.DmnDecisionTableResult; import java.util.Map; public class MultiOutputMapper implements DecisionResultMapper { @Override public Object mapDecisionResult(DmnDecisionTableResult result) { // Return the first matching row as a Map (adjust if you need multiple rows) return result.isEmpty() ? null : result.singleResult(); } } - Register the mapper in your Camunda engine configuration (via XML or Java config)
- Select your custom mapper in the Business Rule Task's Decision Result Mapper dropdown
- Then use the multi-result mappings from Option 1 to split the map into variables.
Quick Note: Double-Check Spelling!
I noticed in your error stack you wrote OUT_CATETORY (extra 'T')—make sure your DMN output column name matches exactly what you use in your expressions. A typo here will cause variables to be null.
内容的提问来源于stack exchange,提问作者Espresso

