Hello,
sry for posting "a little" late. Until now we bypassed the problem, but now we need to reconsider a solution to this problem.
Basically a user is able to "empty" a textfield from the UI-Point of view. Until now, we putted an empty string, which worked fine.
But for Data-Maintenance Reasons we need to store a null value instead of an empty string, whenever a user is going to empty the text-field.
Therefore we setup the following in the web.xml:
<context-param>
<param-name>
javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL
</param-name>
<param-value>true</param-value>
</context-param>
So, what has this to do with activiti?
Our form-elements are directly bounded to the entry in the ProcessvariableMap. Using a JSF 2.2 ViewScope, we perform some Ajax Operations and finally the submission of the form.
Every change to a field is stored properly, eccept when it resolves to `null`. We followed the Stacktrace down to the `ConversationScopeAssociation` of `DefaultContextAssociationManager` and found the following piece of code being executed:
DefaultContextAssociationManager
@Override
public Object getVariable(String variableName) {
ExecutionEntity execution = getExecutionFromContext();
if(execution != null) {
return execution.getVariable(variableName);
} else {
return getScopedAssociation().getVariable(variableName);
}
}
Here, execution will resolve to null, and the else-case will call the ConversationScopedAssociation:
public <T> T getVariable(String variableName) {
Object value = cachedVariables.get(variableName);
if(value == null) {
if(execution != null) {
value = runtimeService.getVariable(execution.getId(), variableName);
cachedVariables.put(variableName, value);
}
}
return (T) value;
}
At this point, the cachedVariable-Map may contain our desired "key=null" - for loging purposes we are iterating over the map and getting the values again, to log the change: And this "removes" the null value from the cachedVariable map:
If the "value" is null - it's reloaded by the runtimeService. However at this point, we did not yet save the variables (flush). That means: the null is removed and the "old" value is restored inside the cachedVariable-Map before actually saving the changes.
I'm not sure wheter this is a bug or serves some purpose, but it looks pretty strange. It is essentially saying: "You are not allowing to have null values in the cachedVariable Map".
So, the current event-sequence is like:
ProcessVariableMap.put("someKey", null); //old value was "Hello World"
-> stored in CachedMap
-> calling ProcessVariableMap.get("someKey") // returns "Hello World", cause of the code outlined above.
-> calling businessProcess.complete() // now stores "Hello World" again, because the getter writes back to the cachedVariable map.
edit: Running on activiti 5.13