我们当前存储在 Camunda 上下文中的数据由嵌套的 java.util.Maps 组成。以下是我们如何将消息关联到引擎,以及传递上下文:
Map<String, Object> context = <construct map>;
var builder = processEngine.getRuntimeService()
.createMessageCorrelation(MESSAGE_NAME)
.processInstanceVariablesEqual(CORRELATIONS)
.setVariables(context);
我们目前面临的问题是如何只更新部分上下文。假设在一个正在运行的进程中,我们有以下上下文:
vendingMachineId: "123",
inventory: [
"coke": ["quantity": 1, price: "10"],
"pepsi": ["quantity": 2, price: "5"]
]
[:]
语法意味着地图。根据我们阅读的内容,库存将作为 LOB 存储在数据库中。有没有办法只更新这个 LOB 的一部分?例如,通过将消息与变量相关联,将百事可乐的数量减少到 1 inventory: [pepsi: ["quantity": 1]]
。有效地执行合并而不是替换。有没有办法自定义上下文的更新方式?
我们发现的一种解决方案 1) 或解决方法是展平地图,以便上下文如下所示:
vendingMachineId: "123",
inventory.coke.quantity: "1",
inventory.coke.price: "10",
inventory.pepsi.quantity: "2",
inventory.pepsi.price: "5"
在这种情况下,我们只能直接替换inventory.pepsi.quantity。但是,这带来了以下缺点:
- 每个正在运行的进程的数据库负载更多,因为每个变量都是单独的行
- BPMN 中变量的使用更加笨拙,因为我们不能再直接使用inventory.pepsi.price,而必须调用execution.getVariable('inventory.pepsi.price')。
作为一种改进,我们可以引入一个自定义函数,比如说 c,并在表达式中调用它 - ${c('inventory').pepsi.price > 10
。这样我们可以保持一个扁平化的上下文,就像在解决方案 1) 中一样,但至少使 bpmn 的使用稍微容易一些。当然,所需的表达式只是${inventory.pepsi.price}
.
PS。从 Camunda论坛回复,希望能获得更多关于这个问题的知名度。