You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-user@db.apache.org by Carl <cb...@visualanalytics.com> on 2003/07/11 16:41:41 UTC

Getting NullPointerException in org.apache.ojb.odmg.ObjectEnvelopeTable.reorderCollection

I'm using version 1.0 rc3 on Windows XP using MS SQLServer.

 

I have an M-to-N association described by the following two class
descriptors.  Many ElementList objects have collections of Element objects.
Element objects in each ElementList objects elementDataList collection can
be shared between one or more ElementList objects.

 

 

   <class-descriptor class="test.ElementList" table="ELEMENT_LIST"
isolation-level="serializable">

      <field-descriptor name="elementListId" column="element_list_id"
jdbc-type="INTEGER" primarykey="true" autoincrement="true"/>

     

      <collection-descriptor

         name="elementDataList"

         element-class-ref="test.Element"

         collection-class="org.apache.ojb.odmg.collections.DListImpl"

         indirection-table="ELEMENT_INDIRECTION_TABLE"

      >

         <fk-pointing-to-this-class column="element_list_id"/>

         <fk-pointing-to-element-class column="element_id"/>

      </collection-descriptor>

 

   <class-descriptor class="test.Element" table="ELEMENT"
isolation-level="serializable">

 

      <field-descriptor name="elementId" column="element_id"
jdbc-type="INTEGER" primarykey="true" autoincrement="true"/>

 

      <field-descriptor name="label" column="label" jdbc-type="VARCHAR"/>

 

      <field-descriptor name="value" column="value1"
jdbc-type="LONGVARBINARY"
conversion="org.apache.ojb.broker.accesslayer.conversions.Object2ByteArrFiel
dConversion"/>

 

   </class-descriptor>

 

 

Another persistent class (not shown here has a reference to the ElementList
class described above.  Multiple instances of this class are WRITE locked
(implicitly) and committed.  A null pointer occurs during the reordering
logic.

 

 

java.lang.NullPointerException

            at
org.apache.ojb.odmg.ObjectEnvelopeTable.reorderCollection(ObjectEnvelopeTabl
e.java:585)

            at
org.apache.ojb.odmg.ObjectEnvelopeTable.reorderObject(ObjectEnvelopeTable.ja
va:519)

            at
org.apache.ojb.odmg.ObjectEnvelopeTable.reorder(ObjectEnvelopeTable.java:466
)

            at
org.apache.ojb.odmg.ObjectEnvelopeTable.commit(ObjectEnvelopeTable.java:186)

            at
org.apache.ojb.odmg.TransactionImpl.doCommitOnObjects(TransactionImpl.java:3
42)

            at
org.apache.ojb.odmg.TransactionImpl.prepare(TransactionImpl.java:595)[org.ap
ache.ojb.odmg.ObjectEnvelopeTable] ERROR: Commit on object level failed for
tx org.apache.ojb.odmg.TransactionImpl@4d37e5 null

 

The line getting the null pointer is noted below.

 

 

    private void reorderCollection(

        Map htNewHashtable,

        List newVector,

        ObjectEnvelope objectToReorder,

        ClassDescriptor cld,

        Map htOldVectorPosition)

        throws IllegalAccessException

    {

        Iterator i;

        i = cld.getCollectionDescriptors().iterator();

        while (i.hasNext())

        {

            CollectionDescriptor cds = (CollectionDescriptor) i.next();

            Object col =
cds.getPersistentField().get(objectToReorder.getObject());

            if (col != null)

            {

                Iterator colIterator;

                if (col instanceof ManageableCollection)

                {

                    colIterator = ((ManageableCollection)
col).ojbIterator();

                }

                else if (col instanceof Collection)

                {

                    colIterator = ((Collection) col).iterator();

                }

                else if (col.getClass().isArray())

                {

                    colIterator = new ArrayIterator(col);

                }

                else

                {

                    throw new OJBRuntimeException(

                        col.getClass()

                            + " can not be managed by OJB, use Array,
Collection or ManageableCollection instead !");

                }

                Object item = null;

                while (colIterator.hasNext())

                {

                    // The collection now contains all the objects in the
collection.

                    // Now we have to retrieve the ObjectEnvelope
representing this

                    // Object from the hashtable, remove it from the vector
and reorder

                    // the retrieved ObjectEnvelope.

                    item = colIterator.next();

                    if(item != null)

                    {

                    Identity id = new Identity(item,
transaction.getBroker());

                    ObjectEnvelope oe = (ObjectEnvelope)
mhtObjectEnvelopes.get(id);

                    if (oe != null)

                    {

                        mvOrderOfIds.set(((Integer)
htOldVectorPosition.get(id)).intValue(), null);    <<<< NullPointerException
occurs here 

                        // mvOrderOfIds.set(mvOrderOfIds.indexOf(id), null);

                        mhtObjectEnvelopes.remove(id);

                        reorderObject(htNewHashtable, newVector, oe, id,
htOldVectorPosition);

                    }

                    }

                }

            }

        }

    }

 

The value retrieved from the htOldVectorPosition is null.

 

 

I modified the section of reorderCollection method to prevent the null
pointer as follows.  This patch gets around the null pointer, but then OJB
gets a SQL error because it attempts to insert a duplicate key into the
indirection table.

 

 

                Integer pos = null;

                while (colIterator.hasNext())

                {

                    // The collection now contains all the objects in the
collection.

                    // Now we have to retrieve the ObjectEnvelope
representing this

                    // Object from the hashtable, remove it from the vector
and reorder

                    // the retrieved ObjectEnvelope.

                    item = colIterator.next();

                    if(item != null)

                    {

                    Identity id = new Identity(item,
transaction.getBroker());

                    ObjectEnvelope oe = (ObjectEnvelope)
mhtObjectEnvelopes.get(id);

                    if (oe != null)

                    {

                        pos = (Integer) htOldVectorPosition.get(id);

                        if(pos != null)

                        {

                        mvOrderOfIds.set(pos.intValue(), null);

                        // mvOrderOfIds.set(mvOrderOfIds.indexOf(id), null);

                        mhtObjectEnvelopes.remove(id);

                        reorderObject(htNewHashtable, newVector, oe, id,
htOldVectorPosition);

                        }

                    }

                    }

                }

 

 

Please let me know if this problem has been corrected or how to properly
fix.  This is a show stopper.

 

Thanks


Re: Getting NullPointerException in org.apache.ojb.odmg.ObjectEnvelopeTable.reorderCollection

Posted by Thomas Mahler <th...@web.de>.
I'll have a look at this.

currently I'm not aware of a bug (and a respective fix) in this area 
since RC3.

cheers,
thomas

Carl wrote:
> I'm using version 1.0 rc3 on Windows XP using MS SQLServer.
> 
>  
> 
> I have an M-to-N association described by the following two class
> descriptors.  Many ElementList objects have collections of Element objects.
> Element objects in each ElementList objects elementDataList collection can
> be shared between one or more ElementList objects.
> 
>  
> 
>  
> 
>    <class-descriptor class="test.ElementList" table="ELEMENT_LIST"
> isolation-level="serializable">
> 
>       <field-descriptor name="elementListId" column="element_list_id"
> jdbc-type="INTEGER" primarykey="true" autoincrement="true"/>
> 
>      
> 
>       <collection-descriptor
> 
>          name="elementDataList"
> 
>          element-class-ref="test.Element"
> 
>          collection-class="org.apache.ojb.odmg.collections.DListImpl"
> 
>          indirection-table="ELEMENT_INDIRECTION_TABLE"
> 
>       >
> 
>          <fk-pointing-to-this-class column="element_list_id"/>
> 
>          <fk-pointing-to-element-class column="element_id"/>
> 
>       </collection-descriptor>
> 
>  
> 
>    <class-descriptor class="test.Element" table="ELEMENT"
> isolation-level="serializable">
> 
>  
> 
>       <field-descriptor name="elementId" column="element_id"
> jdbc-type="INTEGER" primarykey="true" autoincrement="true"/>
> 
>  
> 
>       <field-descriptor name="label" column="label" jdbc-type="VARCHAR"/>
> 
>  
> 
>       <field-descriptor name="value" column="value1"
> jdbc-type="LONGVARBINARY"
> conversion="org.apache.ojb.broker.accesslayer.conversions.Object2ByteArrFiel
> dConversion"/>
> 
>  
> 
>    </class-descriptor>
> 
>  
> 
>  
> 
> Another persistent class (not shown here has a reference to the ElementList
> class described above.  Multiple instances of this class are WRITE locked
> (implicitly) and committed.  A null pointer occurs during the reordering
> logic.
> 
>  
> 
>  
> 
> java.lang.NullPointerException
> 
>             at
> org.apache.ojb.odmg.ObjectEnvelopeTable.reorderCollection(ObjectEnvelopeTabl
> e.java:585)
> 
>             at
> org.apache.ojb.odmg.ObjectEnvelopeTable.reorderObject(ObjectEnvelopeTable.ja
> va:519)
> 
>             at
> org.apache.ojb.odmg.ObjectEnvelopeTable.reorder(ObjectEnvelopeTable.java:466
> )
> 
>             at
> org.apache.ojb.odmg.ObjectEnvelopeTable.commit(ObjectEnvelopeTable.java:186)
> 
>             at
> org.apache.ojb.odmg.TransactionImpl.doCommitOnObjects(TransactionImpl.java:3
> 42)
> 
>             at
> org.apache.ojb.odmg.TransactionImpl.prepare(TransactionImpl.java:595)[org.ap
> ache.ojb.odmg.ObjectEnvelopeTable] ERROR: Commit on object level failed for
> tx org.apache.ojb.odmg.TransactionImpl@4d37e5 null
> 
>  
> 
> The line getting the null pointer is noted below.
> 
>  
> 
>  
> 
>     private void reorderCollection(
> 
>         Map htNewHashtable,
> 
>         List newVector,
> 
>         ObjectEnvelope objectToReorder,
> 
>         ClassDescriptor cld,
> 
>         Map htOldVectorPosition)
> 
>         throws IllegalAccessException
> 
>     {
> 
>         Iterator i;
> 
>         i = cld.getCollectionDescriptors().iterator();
> 
>         while (i.hasNext())
> 
>         {
> 
>             CollectionDescriptor cds = (CollectionDescriptor) i.next();
> 
>             Object col =
> cds.getPersistentField().get(objectToReorder.getObject());
> 
>             if (col != null)
> 
>             {
> 
>                 Iterator colIterator;
> 
>                 if (col instanceof ManageableCollection)
> 
>                 {
> 
>                     colIterator = ((ManageableCollection)
> col).ojbIterator();
> 
>                 }
> 
>                 else if (col instanceof Collection)
> 
>                 {
> 
>                     colIterator = ((Collection) col).iterator();
> 
>                 }
> 
>                 else if (col.getClass().isArray())
> 
>                 {
> 
>                     colIterator = new ArrayIterator(col);
> 
>                 }
> 
>                 else
> 
>                 {
> 
>                     throw new OJBRuntimeException(
> 
>                         col.getClass()
> 
>                             + " can not be managed by OJB, use Array,
> Collection or ManageableCollection instead !");
> 
>                 }
> 
>                 Object item = null;
> 
>                 while (colIterator.hasNext())
> 
>                 {
> 
>                     // The collection now contains all the objects in the
> collection.
> 
>                     // Now we have to retrieve the ObjectEnvelope
> representing this
> 
>                     // Object from the hashtable, remove it from the vector
> and reorder
> 
>                     // the retrieved ObjectEnvelope.
> 
>                     item = colIterator.next();
> 
>                     if(item != null)
> 
>                     {
> 
>                     Identity id = new Identity(item,
> transaction.getBroker());
> 
>                     ObjectEnvelope oe = (ObjectEnvelope)
> mhtObjectEnvelopes.get(id);
> 
>                     if (oe != null)
> 
>                     {
> 
>                         mvOrderOfIds.set(((Integer)
> htOldVectorPosition.get(id)).intValue(), null);    <<<< NullPointerException
> occurs here 
> 
>                         // mvOrderOfIds.set(mvOrderOfIds.indexOf(id), null);
> 
>                         mhtObjectEnvelopes.remove(id);
> 
>                         reorderObject(htNewHashtable, newVector, oe, id,
> htOldVectorPosition);
> 
>                     }
> 
>                     }
> 
>                 }
> 
>             }
> 
>         }
> 
>     }
> 
>  
> 
> The value retrieved from the htOldVectorPosition is null.
> 
>  
> 
>  
> 
> I modified the section of reorderCollection method to prevent the null
> pointer as follows.  This patch gets around the null pointer, but then OJB
> gets a SQL error because it attempts to insert a duplicate key into the
> indirection table.
> 
>  
> 
>  
> 
>                 Integer pos = null;
> 
>                 while (colIterator.hasNext())
> 
>                 {
> 
>                     // The collection now contains all the objects in the
> collection.
> 
>                     // Now we have to retrieve the ObjectEnvelope
> representing this
> 
>                     // Object from the hashtable, remove it from the vector
> and reorder
> 
>                     // the retrieved ObjectEnvelope.
> 
>                     item = colIterator.next();
> 
>                     if(item != null)
> 
>                     {
> 
>                     Identity id = new Identity(item,
> transaction.getBroker());
> 
>                     ObjectEnvelope oe = (ObjectEnvelope)
> mhtObjectEnvelopes.get(id);
> 
>                     if (oe != null)
> 
>                     {
> 
>                         pos = (Integer) htOldVectorPosition.get(id);
> 
>                         if(pos != null)
> 
>                         {
> 
>                         mvOrderOfIds.set(pos.intValue(), null);
> 
>                         // mvOrderOfIds.set(mvOrderOfIds.indexOf(id), null);
> 
>                         mhtObjectEnvelopes.remove(id);
> 
>                         reorderObject(htNewHashtable, newVector, oe, id,
> htOldVectorPosition);
> 
>                         }
> 
>                     }
> 
>                     }
> 
>                 }
> 
>  
> 
>  
> 
> Please let me know if this problem has been corrected or how to properly
> fix.  This is a show stopper.
> 
>  
> 
> Thanks
> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-user-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-user-help@db.apache.org