AnsweredAssumed Answered

Activiti flushes and commits read only Spring transaction

Question asked by mdond on Dec 18, 2012
Latest reply on Dec 18, 2012 by jbarrez
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(
   at org.activiti.engine.impl.interceptor.CommandContext.flushSessions(
   at org.activiti.engine.impl.interceptor.CommandContext.close(
   at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(
   at org.activiti.spring.SpringTransactionInterceptor$1.doInTransaction(
   at org.activiti.spring.SpringTransactionInterceptor.execute(
   at org.activiti.engine.impl.interceptor.LogInterceptor.execute(
   at org.activiti.engine.impl.RuntimeServiceImpl.getVariable(
   … 118 more
Caused by: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing:

with the following call from our Spring service bean:

    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()) {

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?