如何配置内存中的 Camunda 数据库以接受更长的字符串过程变量?

Posted

技术标签:

【中文标题】如何配置内存中的 Camunda 数据库以接受更长的字符串过程变量?【英文标题】:How can I configure the in-memory Camunda database to accept longer string process variables? 【发布时间】:2015-10-27 11:41:34 【问题描述】:
[error]  org.h2.jdbc.JdbcSQLException: Value too long for column "TEXT_ VARCHAR(4000)":

Camunda 需要通过一些 ALTER TABLE 语句进行配置,以允许数据库中非常长的 String 类型的流程变量。

如何为内存单元测试数据库执行此操作(由于数据库是瞬态的,没有管理工具来修改架构)?

或者是否可以选择将字符串存储为二进制序列化,就像 Java 对象(显然可以更长)而不是文本列?

【问题讨论】:

【参考方案1】:

我找到了thread about the subject 并扩展了那里提出的“hacky workaround”,我可以通过将这段代码放在设置阶段来使我的测试用例通过:

// allow longer texts:
// https://forums.activiti.org/content/increase-lenght-string-process-variables

val processEngineConfiguration = engine.getProcessEngineConfiguration()
val session = processEngineConfiguration
     .asInstanceOf[ProcessEngineConfigurationImpl]
     .getDbSqlSessionFactory().getSqlSessionFactory().openSession();
val connection = session.getConnection()
val jdbcStatement = connection.createStatement()
jdbcStatement.execute("ALTER TABLE ACT_RU_VARIABLE ALTER TEXT_ CLOB");
jdbcStatement.execute("ALTER TABLE ACT_HI_VARINST ALTER TEXT_ CLOB");
jdbcStatement.execute("ALTER TABLE ACT_HI_DETAIL ALTER TEXT_ CLOB");
jdbcStatement.close();

【讨论】:

gist.github.com/o-nix/a036f5a83c4a5b3a98c7?ts=2 使用您的代码配置 bean。【参考方案2】:

要回答你的最后一个问题,试试这个:

RuntimeService runtimeService = processEngine.getRuntimeService();

VariableMap variables = Variables.createVariables();
variables.putValueTyped("var", Variables
          .objectValue(aLongStringValue)
              // tells the engine to use java serialization for persisting the value 
          .serializationDataFormat(SerializationDataFormats.JAVA)  
          .create());

// Start a process instance
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testProcess", variables);

这种方法的局限性在于:

您不能在查询中使用此变量,例如runtimeService.createVariableInstanceQuery().variableValueEquals("var", aLongStringValue).list() 找不到该变量 无论何时获取变量,都必须使用返回反序列化值的 API(例如 RuntimeService.getVariable("name") or RuntimeService.getVariableTyped("name", true))来获取实际值。如果您依赖于引擎可以以序列化格式提供变量的功能,这可能是一个问题(对于普通的String 变量,只是普通的String 值;对于Java 序列化的Object 值,它是字节表示的 base64 编码字符串)。

【讨论】:

getVariable("key") 仍然可以。使用getVariableTyped("key", false),您将无法再检索实际的字符串值。我的表述不准确,我会更新它。 另外,在设置它的代码中,我是否需要提前知道变量名(这里是"var")?可以为所有字符串全局设置吗? 我假设您的意思是变量值的类型,对吧?仅使用公共 API,您将需要标识 String 值的代码,并使用上面的代码来创建对象值。要始终通过 Java 对象序列化来序列化字符串,您还可以从引擎配置中删除 StringValueSerializer(请参阅 org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl#initSerialization)。这可以通过创建自定义引擎配置类或可能从流程引擎插件中完成。【参考方案3】:

如果你在 Spring Boot jar 中使用 Camunda,你可以在其中添加一个 data.sql /src/main/resources 和更新语句。

ALTER TABLE ACT_RU_VARIABLE ALTER TEXT_ CLOB;
ALTER TABLE ACT_HI_VARINST ALTER TEXT_ CLOB;
ALTER TABLE ACT_HI_DETAIL ALTER TEXT_ CLOB;

【讨论】:

以上是关于如何配置内存中的 Camunda 数据库以接受更长的字符串过程变量?的主要内容,如果未能解决你的问题,请参考以下文章

如何清理卡蒙达历史

如何从 Camunda 中的 EnumFormType 重置值?

camunda开源流程引擎的数据库表结构介绍

开源流程引擎Camunda BPM如何扩展数据库表

Camunda Spring启动事务问题

如何使用cli将历史级别更改为camunda中的活动