AnsweredAssumed Answered

VariableInstanceEntity saves value twice for new variables

Question asked by naag on Jul 5, 2012
Latest reply on Jul 5, 2012 by frederikheremans1
Hi all,

I'm trying to implement a custom VariableType (based on MongoDB) and noticed that VariableType.setValue() will be called twice when the affected variable did not yet exist in the current scope. The first call creates the new VariableInstanceEntity via VariableScopeImpl.createVariableLocal() and saves it immediately. The second call happens right afterwards via VariableScopeImpl.setVariableInstanceValue(), and just saves the exact same data again. The only thing happening in between the two calls is back pointer initialization. The code in question:


public void createVariableLocal(String variableName, Object value) {
   ensureVariableInstancesInitialized();

   if (variableInstances.containsKey(variableName)) {
      throw new ActivitiException("variable '" + variableName
            + "' already exists. Use setVariableLocal if you want to overwrite the value");
   }

   VariableTypes variableTypes = Context.getProcessEngineConfiguration().getVariableTypes();

   VariableType type = variableTypes.findVariableType(value);

   // ***** First call to VariableType.setValue() from inside here
   VariableInstanceEntity variableInstance = VariableInstanceEntity.createAndInsert(variableName, type, value);
   initializeVariableInstanceBackPointer(variableInstance);
   variableInstances.put(variableName, variableInstance);

   // ***** Second call to VariableType.setValue() from inside here
   setVariableInstanceValue(value, variableInstance);
}

In my case this brings to issues:

  • My implementation of VariableType will commit a new record to MongoDB every time that VariableType.setValue() is called. The intention is to trace every update to the variables. If setValue() is called twice, there will be two records in MongoDB.

  • I would like to add some additional attributes to the MongoDB documents, namely the Process Instance ID, Execution ID and Task ID (if available). But during the first call to setValue(), the VariableInstanceEntity is not completely initialized because VariableScopeImpl.initializeVariableInstanceBackPointer() has not been called yet. With the second call, the back pointers are there. So I can cast the valueFields argument to VariableInstanceEntity and get the data.
Now the first issue I can solve by introducing something like a "dirty" field in my variables, so my VariableType will only save the record when there were changes in the data. But I have no idea how I can obtain the details about the current execution.

I tried via Context.getExecutionContext().getExecution() from my VariableType, but face a EmptyStackException :-(

So my two questions are:

  • Am I missing something about VariableType.save() being called twice? Or is it a defect?

  • Is there any way I can obtain the current execution entity (either TaskEntity or ExecutionEntity)? I was thinking to obtain an instance of BusinessProcess CDI bean, but it feels hacky to me.
Thank you for all ideas :-)

Regards,
Peter

Outcomes