Uploaded image for project: 'Application Server 3  4  5 and 6'
  1. Application Server 3 4 5 and 6
  2. JBAS-2643

Map, possibly Set, silent persistence failure in 4.0.2

XMLWordPrintable

      This is a nasty one.

      If you define an entity bean field as a TreeMap and run a series of EJB accesses (under different transactions - I used individual MDB accesses), the accesses subsequent to one which modifies the field won't see the changes.

      I turned on DEBUG logging and found the problem. Although a print in the ejbStore() method shows the modifications correctly, the next ejbLoad() has lost them. The reason is that
      org.jboss.ejb.plugins.cmp/jdbc/JDBCTypeFactory.java
      has the following code:

      /**

      • Field state factory for java.util.Map implementations. The state is
      • a deep copy of the value.
        */
        private static final CMPFieldStateFactory MAP = new CMPFieldStateFactory()
        {
        public Object getFieldState(Object fieldValue)
        {
        return fieldValue == null ? null : new HashMap((Map)fieldValue);
        }

      public boolean isStateValid(Object state, Object fieldValue)
      {
      return (state == null ? fieldValue == null : state.equals(fieldValue));
      }
      };

      This maps all "Map" implementations to a HashMap as a state value. Later on, when "isStateValid" is called, the saved state is always a HashMap, while the fieldValue will be whatever Map implementation the implementor chose, e.g. TreeMap. This causes isStateValid() to return "false", which causes the following code in JDBCCMP2xFieldBridge to report that the field is not dirty, thus causing it not to be persisted:

      /**

      • @return true if the field is dirty.
        */
        public boolean isDirty()
        {
        return isLoaded() && !stateFactory.isStateValid(state, value);
        }

      I changed my app to use TreeMap from TreeSet before digging in to debug this, so I suspect that Sets are treated in the same way, since I saw the same problem with a TreeSet.

      I'm sure there is probably a good reason for the isStateValid() test, but the silent failure in this case can easily lead to data corruption.

              olubyans@redhat.com Alexey Loubyansky
              ftg314159 Francis Griffin (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

                Created:
                Updated:
                Resolved: