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

Usage of read-ahead on-find with entity beans containing binary attributes (mapped to BLOB, VARBINAR, ...) breaks eager loading.

    XMLWordPrintable

Details

    Description

      I' ve found out that using the read ahead strategy "on-find" on an EJB2 entity bean which contains at least one binary persistent attribute (e.g public abstract byte[] getBinaryImage() can break the eager loading of attributes causing "strange" exceptions.

      It is related to the fix of issue http://jira.jboss.org/jira/browse/JBAS-3800.

      This fix brought in the following code to the JDBCEJBQLQuery.java

      // exclude non-searchable columns if distinct is used
      if(compiler.isSelectDistinct())
      {
      boolean[] mask = getEagerLoadMask();
      JDBCFieldBridge[] tableFields = selectEntity.getTableFields();
      for(int i = 0; i < tableFields.length; ++i)
      {
      if(mask[i] && !tableFields[i].getJDBCType().isSearchable())

      { mask[i] = false; }

      Manipulation of mask[i] has the side effect to be visible on ALL finders defined for entity because the mask array is hold by JDBCEntityBridge and shared through all JDBCAbstractQueryCommand instances referencing to this JDBCEntityBridge as selectEntity.

      Executing an non distinct query on the bean can cause calls with wrong parameters to the method loadArgumentResults in
      JDBCAbstractQueryCommand.EagerCollectionFactory at line 756 and the following.

      JDBCFieldBridge[] tableFields = selectEntity.getTableFields();
      for(int i = 0; i < eagerLoadMask.length; i++)
      {
      if(eagerLoadMask[i])
      {
      JDBCFieldBridge field = tableFields[i];
      ref[0] = null;

      // read the value and store it in the readahead cache
      index = field.loadArgumentResults(rs, index, ref);

      if(addPk)

      { selectReadAheadCache.addPreloadData(curPk, field, ref[0]); }

      }
      }

      Depending on the order of declaring the ejb-find methods for the entity the sql-string of an JDBCAbstractQueryCommand instance maybe compiled before the mask array is changed (by compiling an dictinct-query). In such cases the jdbc-resultset contains the binary column but the if-statement if(eagerLoadMask[i]) skip to load it into the JDBCFieldBridge object. An increment on the index variable (which point to the position to process next from the resultset) is skipped too. Processing the following result set columns cause errors because now JDBC-type at position index does not match the JDBCFieldBridge at tableFields[i].

      Attachments

        Issue Links

          Activity

            People

              olubyans@redhat.com Alexey Loubyansky
              mrothe_jira Rothe Marco (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: