AnsweredAssumed Answered

ByteArrayEntity: improve encapsulation

Question asked by marcus1 on May 13, 2013
Latest reply on Jun 10, 2013 by frederikheremans1
I've run into a nasty bug in a custom variable type causing Foreign Key Constaint error in ACT_FK_VAR_BYTEARRAY.

The first part of solving the problem was to improve logging in DbSqlSession. This helped me diagnose what went wrong. These changes you can find in this pull request:

https://github.com/Activiti/Activiti/pull/66

Our custom variable type stores a list of JPA entities by storing the elements' ids in a the textValue field, and if it becomes too long, in a byte array field:

      String s = buffer.toString();
      if (s.length() > MAX_STR_LENGTH) {
         fields.setByteArrayValue(bytes);
         fields.setTextValue(null);
      }
      else {
         fields.setTextValue(s.length() == 0 ? null : s);
         fields.setByteArrayValue(null);
      }

It turned out that the problem was that if setByteArrayValue is called multiple times, a new ByteArrayEntity is created each time.

Also, the foreign key byteArrayValueId in VariableInstanceEntity is updated, but this change is written to the db before the ByteArrayEntity is inserted, causing the Foreign Key Constaint violation.

So to avoid this problem we have to do:

      if (fields.getByteArrayValueId() != null) {
         fields.getByteArrayValue().setBytes(bytes);
      }
      else {
         fields.setByteArrayValue(bytes);
      }

This is a problem of encapsulation. It is not obvious from the ValueFields interface that this is necessary, and thus quite error prone. Also it's inconsistent with how other entities work.

I'd like to change this and create a new pull request for it, but first wanted to check if it's okay with you.

While I'm at it, there are some changes to DbSqlSession I'd like to make:
- remove commented-out code
- move inner classes to bottom
- improve readability by extracting some common code

What do you think?

Outcomes