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 [EMAIL PROTECTED] 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