cancel
Showing results for 
Search instead for 
Did you mean: 

issues about setting multiple variables

changxl
Champ in-the-making
Champ in-the-making
Hi,
   I am a developer who has used activiti for 3 years.Recently I tried to upgrade my older version(5.13) to 5.21.0 and I had some big problems, all my code are throwing exceptions at runtime! I worked hard to find the reason for 2 days. I 've tried many versions of activiti
and studied the source code and I have some bugs(or maybe not) to feedback.
   Here is the problem: in the newest version(6.0.0.Beta2) or recent versions ,like 5.21.0 down to 5.18.0 (5.16 is ok),when I put multi varibles at one time,and when I start the process or complete user tasks,there will always be an exception (Cause: org.h2.jdbc.JdbcSQLException: Serialization failed)! It is very easy to reproduce the scenario:
        Map<String, Object> variableMap = new HashMap<String, Object>();
   variableMap.put("var1", "var1");
   variableMap.put("var2", "var2");
   ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("AnyProcessDefKey", variableMap);
   So I studied vary version's code and compare the differences between each other and finally find that ,in recent activiti versions, there are many newly added bulk operation like "bulkInsertHistoricDetailVariableInstanceUpdate" or bulkInsertXXXXXX, of course the popurse is to improve the performance,I think.And the exception will be thrown in the versions which has the "bulkXX" methods.
     according to the exception stack,I modified the mybatis mapping files and solved the problem temporarily,but I don't think it's the best solution, Here is my approach :
    in file HistoricDetail.xml ,insert id="bulkInsertHistoricVariableInstance" & id="bulkInsertHistoricDetailVariableInstanceUpdate_oracle",I modified the sql's two parameters:
1. #{historicDetailVariableInstance.variableType, jdbcType=VARCHAR} –>#{historicDetailVariableInstance.variableTypeName, jdbcType=VARCHAR}
2.#{historicDetailVariableInstance.byteArrayRef, typeHandler=ByteArrayRefTypeHandler} –> #{historicDetailVariableInstance.byteArrayRef.id, jdbcType=VARCHAR}
   and in file HistoricVariableInstance.xml, I made the same changes.
   Although this is enough to solve my problem but I still deadly wonder the reason.
   For one hand,I think multi varibles is allowed because the parameter is a Map type and It does work fine in lower version,like 5.16;for another hand , I didn't see any other user have met the same problem like me and there's no same questions in the forum or other website.
   look forward for your replys !Anybody plz help!  Sorry for the bad English,this is my first one..
  
6 REPLIES 6

changxl
Champ in-the-making
Champ in-the-making
I also tried the set methods
runtimeService.setVariable(processInstance.getId(), "var1", "value1");
runtimeService.setVariable(processInstance.getId(), "var2", "value2");
or
taskService.setVariables(task.getId(), MultivariableMap)

and met the same problems, Maybe there's another way I haven't find?

martin_grofcik
Confirmed Champ
Confirmed Champ
Hi,

I have checked org.activiti.engine.test.api.variables.VariablesTest#setUp. The setUp method performs exactly the same scenario as you describe (set variables, start process) and it works fine (on h2 db).

@Joram: Is the build failing on the Oracle DB?

Regards
Martin

Thank you for your replay!Can you tell me which versin you checked?
In my environment both h2 and oracle failed….

changxl
Champ in-the-making
Champ in-the-making
I just tested in version 5.19.0 .Here is my code.
<java>
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath*:spring/spring-activiti.xml",
  "classpath*:spring/spring-datasource-test.xml", "classpath*:spring/spring-transaction.xml" })
public class VeriablesTest {

@Resource
private RuntimeService runtimeService;

@Test
public void simpleSpringTest() throws Exception {
  Map<String, Object> variableMap = new HashMap<String, Object>();
  variableMap.put("var1", "var1");
  variableMap.put("var2", "var2");
  ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("CanotSerializable", variableMap);
}
}
</java>

Here is the config:
spring-datasource.xml
<code>
<bean id="dataSource"
  class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName">
   <value>org.h2.Driver</value>
  </property>
  <property name="url">
   <value>jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000</value>
  </property>
  <property name="username">
   <value>sa</value> 
  </property>
  <property name="password">
   <value></value>
  </property>
</bean>
</code>

and process Definition:
<code>
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlnsSmiley Surprisedmgdc="http://www.omg.org/spec/DD/20100524/DC" xmlnsSmiley Surprisedmgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.bpmnwithactiviti.org">
  <process id="CanotSerializable" name="CanotSerializable" isExecutable="true">
    <startEvent id="startevent1" name="Start"></startEvent>
    <userTask id="usertask1" name="User Task"></userTask>
    <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
    <userTask id="usertask2" name="User Task2"></userTask>
    <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow>
    <endEvent id="endevent1" name="End"></endEvent>
    <sequenceFlow id="flow3" sourceRef="usertask2" targetRef="endevent1"></sequenceFlow>
  </process>
</definitions>

</code>


spring-activiti.xml

<code>
<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
  <property name="databaseType" value="h2" />
  <property name="dataSource" ref="dataSource" />
  <property name="transactionManager" ref="transactionManager" />
  <property name="databaseSchemaUpdate" value="true" />
  <property name="deploymentResources">
   <list>
    <value>classpath*Smiley Tonguerocesses/*</value>
   </list>
  </property>
  <property name="jobExecutorActivate" value="false" />
  <property name="activityFontName" value="宋体"></property>
  <property name="labelFontName" value="宋体"/>
  <!– <property name="annotationFontName" value="宋体"/> –>
  <property name="history" value="full"/>
 
</bean>
<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
  <property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean>
<bean id="repositoryService" factory-bean="processEngine"
  factory-method="getRepositoryService" />
<bean id="runtimeService" factory-bean="processEngine"
  factory-method="getRuntimeService" />
<bean id="taskService" factory-bean="processEngine"
  factory-method="getTaskService" />
<bean id="historyService" factory-bean="processEngine"
  factory-method="getHistoryService" />
<bean id="managementService" factory-bean="processEngine"
  factory-method="getManagementService" />
</code>


the error message

### Error updating database.  Cause: org.h2.jdbc.JdbcSQLException: Serialization failed, cause: "java.io.NotSerializableException: org.activiti.engine.impl.variable.StringType" [90026-170]
### The error may involve org.activiti.engine.impl.persistence.entity.HistoricDetailEntity.bulkInsertHistoricDetailVariableInstanceUpdate-Inline
### The error occurred while setting parameters
### SQL: insert into ACT_HI_DETAIL (ID_, TYPE_, PROC_INST_ID_, EXECUTION_ID_, ACT_INST_ID_, TASK_ID_, NAME_, REV_, VAR_TYPE_, TIME_, BYTEARRAY_ID_, DOUBLE_, LONG_ , TEXT_, TEXT2_)     values                   (?,          ?,          ?,          ?,          ?,          ?,          ?,          ?,          ?,          ?,          ?,          ?,          ?,          ?,          ?)        ,          (?,          ?,          ?,          ?,          ?,          ?,          ?,          ?,          ?,          ?,          ?,          ?,          ?,          ?,          ?)
### Cause: org.h2.jdbc.JdbcSQLException: Serialization failed, cause: "java.io.NotSerializableException: org.activiti.engine.impl.variable.StringType" [90026-170]
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:23)
at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:147)
at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:134)
at org.activiti.engine.impl.db.DbSqlSession.flushBulkInsert(DbSqlSession.java:843)
at org.activiti.engine.impl.db.DbSqlSession.flushPersistentObjects(DbSqlSession.java:812)
at org.activiti.engine.impl.db.DbSqlSession.flushInserts(DbSqlSession.java:790)
at org.activiti.engine.impl.db.DbSqlSession.flush(DbSqlSession.java:611)
at org.activiti.engine.impl.interceptor.CommandContext.flushSessions(CommandContext.java:212)
at org.activiti.engine.impl.interceptor.CommandContext.close(CommandContext.java:138)
at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:66)
at org.activiti.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:47)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:131)
at org.activiti.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:45)
at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:37)
at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:40)
at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:35)
at org.activiti.engine.impl.RuntimeServiceImpl.startProcessInstanceByKey(RuntimeServiceImpl.java:77)
at com.haier.gems.activiti.VeriablesTest.simpleSpringTest(VeriablesTest.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

And I switched the version to 5.16 in my pom.xml,everything works fine…………

martin_grofcik
Confirmed Champ
Confirmed Champ
Hi,

I used upstream/Activiti6. Could you create jUnit test https://forums.activiti.org/content/sticky-how-write-unit-test

Regards
Martin

Dear Martin
I have followed your instruction and created Junit test and I found everything worked correctly! So I back to my project and inspected my pom.xml file carefully.
finally I found my  mybatis-spring dependency's version is 1.1.1,and It's a very old version and maybe has some conflicts with activiti's mybatis dependency.When I changed it to 1.3.0 ,everything worked correctly!(But still I don't know the exact reason)
Thank you for your help!I appreciate it very much