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

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

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

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

【问题讨论】:

    标签: h2 camunda


    【解决方案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();
    

    【讨论】:

    【解决方案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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-08
      • 2020-05-30
      • 2010-10-02
      • 2019-09-19
      相关资源
      最近更新 更多