We use a long running conversation as proposed in 'Java Persistence with Hibernate' chapter 11.2.3 'Extending a Session for a conversation'. During a conversation the flush mode of the Hibernate session is set to FlushMode.MANUAL so changes to the session are not persisted to the database.However activiti (v5.10) seems to flush the hibernate session when reading a variable.We get the following error when using activiti (v5.10), which is caused because the changes are flushed when they shouldn't (the transient instance will be persisted later on and then the flush will work right). The flush is caused by Activiti:
org.activiti.engine.ActivitiException: Error while flushing EntityManager, illegal state
at org.activiti.engine.impl.variable.EntityManagerSessionImpl.flush(EntityManagerSessionImpl.java:56)
at org.activiti.engine.impl.interceptor.CommandContext.flushSessions(CommandContext.java:157)
at org.activiti.engine.impl.interceptor.CommandContext.close(CommandContext.java:109)
at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:49)
at org.activiti.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:42)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:130)
at org.activiti.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:40)
at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:33)
at org.activiti.engine.impl.RuntimeServiceImpl.getVariable(RuntimeServiceImpl.java:103)
at org.company.service.workflow.WorkflowManagerImpl.getProcessVariable(WorkflowManagerImpl.java:1240)
…..
… 118 more
Caused by: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: org.company.model.DocumentVersion
with the following call from our Spring service bean:
@Autowired
private RuntimeService actRuntimeService = null;
@Transactional(readOnly = true)
public Object getProcessVariable(String executionId, String variableName)
{
return actRuntimeService.getVariable(executionId, variableName);
}
To us it seems the code in CommandContext is wrong, as it flushes the EntityManager even if it is set to FlushMode.MANUAL and the transaction is readOnly.
protected void flushSessions() {
for (Session session : sessions.values()) {
session.flush();
}
}
As an additional info to the problem: If we read a Task variable instead of a Process variable everything works fine:
@Transactional(readOnly = true)
public Object getTaskVariable(String taskId, String variableName)
{
return actTaskService.getVariableLocal(taskId, variableName);
}
Is there a way to use Activiti in the context of a long running conversation without this problem?