Hi Jakob,
I have some more information for you. The primary keys are all
java.lang.Integer. The problem is occuring because my persistence descriptor
uses an Interface rather than an actual class, and on the load operation uses
the row reader creates the UserVO. I'm doing this because Users are passed
around my system as interfaces, so I'd rather have the persistence acting on the
interface rather than the value object. If there's not an easy way around this,
I'll just switch it back to the value object in the persistence layer. However
the Identity object seems to handle inheritences in it's constructure (where it
takes the real class and the mapped class). Anything you could suggest would be
greatly appreciated. My first preference is to keep the mapping at the
interface level as it's cleaner for my design, and this would also allow other
heirarchies to be accomodated (simple inheritance).
By putting some system outs in the code I get the following, what you can see
from this is that all other vars (pks) are equal, but the Identity objects
differ in that one reverences com.interlinkj.ac.UserVO (the value object
implementation) and the other references com.interlinkj.ac.User (the interface).
:code:
376 // initialize the owner list map
377 for (Iterator it = owners.iterator(); it.hasNext();)
378 {
379 Object owner = it.next();
380 Identity ident = new Identity(owner, pb);
381 System.out.println("original owner pks");
382 Object[] pks = ident.getPrimaryKeyValues();
383 for(int i = 0; i < pks.length; i++){
384 System.out.println("key: " + pks[i]);
385 System.out.println("key: " + pks[i].getClass().getName());
386 }
387 ownerIdsToLists.put(new Identity(owner, pb), new ArrayList());
388 }
389
390 // build the children map
391 for (Iterator it = children.iterator(); it.hasNext();)
392 {
393 Object child = it.next();
394 childMap.put(new Identity(child, pb), child);
395 }
396
397 int ownerPkLen = getOwnerClassDescriptor().getPkFields().length;
398 int childPkLen = getItemClassDescriptor().getPkFields().length;
399 Object[] ownerPk = new Object[ownerPkLen];
400 Object[] childPk = new Object[childPkLen];
401
402 // build list of children based on m:n implementors
403 for (Iterator it = mToNImplementors.iterator(); it.hasNext();)
404 {
405 Object[] mToN = (Object[]) it.next();
406
407 System.out.println("mToN");
408 for(int i = 0; i < mToN.length; i++){
409 System.out.println(mToN[i]);
410 System.out.println(mToN[i].getClass().getName());
411 }
412 System.out.println("mToN done");
413
414 System.arraycopy(mToN, 0, ownerPk, 0, ownerPkLen);
415 System.arraycopy(mToN, ownerPkLen, childPk, 0, childPkLen);
416
417 System.out.println("ownerPk");
418 for(int i = 0; i < ownerPk.length; i++){
419 System.out.println(ownerPk[i]);
420 System.out.println(ownerPk[i].getClass().getName());
421 }
422 System.out.println("ownerPk done");
423 System.out.println("childPk");
424 for(int i = 0; i < childPk.length; i++){
425 System.out.println(childPk[i]);
426 System.out.println(childPk[i].getClass());
427 }
428 System.out.println("childPk done");
429
430 System.out.println("ownerTopLevelClass: " +
ownerTopLevelClass.getName());
431 System.out.println("childTopLevelClass: " +
childTopLevelClass.getName());
432
433 Identity ownerId = new Identity(null, ownerTopLevelClass,
ownerPk);
434 Identity childId = new Identity(null, childTopLevelClass,
childPk);
435
436 for(final Iterator iter =
ownerIdsToLists.keySet().iterator(); iter.hasNext(); ){
437 Identity key = (Identity) iter.next();
438 System.out.println("OwnerId: " + ownerId);
439 System.out.println("key: " + key);
440 System.out.println("OwnerId hashcode: " +
ownerId.hashCode());
441 System.out.println("key hashcode: " + key.hashCode());
442 System.out.println("equal? " + ownerId.equals(key));
443 }
444
445 // Identities may not be equal due to type-mismatch
446 Collection list = (Collection) ownerIdsToLists.get(ownerId);
447 Object child = childMap.get(childId);
448 list.add(child);
449 }
:output:
original owner pks
key: 1
key: java.lang.Integer
mToN
1
java.lang.Integer
1
java.lang.Integer
mToN done
ownerPk
1
java.lang.Integer
ownerPk done
childPk
1
class java.lang.Integer
childPk done
ownerTopLevelClass: com.interlinkj.ac.User
childTopLevelClass: com.interlinkj.ac.Group
OwnerId: com.interlinkj.ac.User{1}
key: com.interlinkj.ac.UserVO{1}
OwnerId hashcode: 597397265
key hashcode: 1028287980
equal? false
Cheers
Adam
Quoting Jakob Braeuchi <[EMAIL PROTECTED]>:
> hi adam,
>
> make sure the instvars representing the pk are of the same type (ie.
> Integer).
> the comment on line 405 points to this direction.
>
> jakob
>
> [EMAIL PROTECTED] schrieb:
> > Hi Jakob,
> >
> > Thanks for the quick response. I'm using the 1.0.1 release.
> >
> > The npe occuring at line 408 (snippet below). In the scenario I'm running
> both
> > 'list' and 'child' are null. The npe is from the 'list.add' call.
> >
> > 405 // Identities may not be equal due to type-mismatch
> > 406 Collection list = (Collection)
> ownerIdsToLists.get(ownerId);
> > 407 Object child = childMap.get(childId);
> > 408 list.add(child);
> >
> > Cheers
> > Adam
> >
> > Quoting Jakob Braeuchi <[EMAIL PROTECTED]>:
> >
> >
> >>hi,
> >>
> >>what version of ojb are you using ? could you please provide the line
> number
> >>
> >>where the npe occurs ?
> >>
> >>jakob
> >>
> >>[EMAIL PROTECTED] schrieb:
> >>
> >>
> >>>
> >>>Hi All,
> >>>
> >>>I'm firing this at both lists as I can't figure out whether it's a bug in
> >>
> >>the
> >>
> >>>code or my mapping.
> >>>
> >>>I'm trying to accomplish a pretty simple mn relationship (user/group type
> >>>arrangement). The mapping file for the section in question is attached
> >>
> >>below.
> >>
> >>> I have some test data (also below, in dbunit dataset format) which I've
> >>>verified in the database and everytime I try to load a group it throws a
> >>
> >>null
> >>
> >>>pointer at me. Any assistance would be appreciated. Let me know if you
> >>
> >>would
> >>
> >>>like any more information.
> >>>
> >>>
> >>>:Mapping File:
> >>>
> >>> <class-descriptor
> >>> class="com.interlinkj.ac.User"
> >>> table="USERS"
> >>> row-reader="com.interlinkj.db.UserRowReader">
> >>> <field-descriptor
> >>> name="id"
> >>> column="id"
> >>> jdbc-type="INTEGER"
> >>> primarykey="true"
> >>> autoincrement="true"/>
> >>> <field-descriptor
> >>> name="firstName"
> >>> column="firstname"
> >>> jdbc-type="VARCHAR"
> >>> nullable="false"/>
> >>> <field-descriptor
> >>> name="lastName"
> >>> column="lastname"
> >>> jdbc-type="VARCHAR"
> >>> nullable="false"/>
> >>> <field-descriptor
> >>> name="userName"
> >>> column="username"
> >>> jdbc-type="VARCHAR"
> >>> nullable="false"/>
> >>> <field-descriptor
> >>> name="passwordHash"
> >>> column="credentials"
> >>> jdbc-type="VARCHAR"
> >>> nullable="false"/>
> >>> <collection-descriptor
> >>> name="groups"
> >>> element-class-ref="com.interlinkj.ac.Group"
> >>> indirection-table="USER_GROUP_LINK"
> >>> auto-delete="link"
> >>> auto-update="object"
> >>> auto-retrieve="true"
> >>> orderby="id"
> >>> sort="ASC"
> >>> >
> >>> <fk-pointing-to-this-class column="user_id"/>
> >>> <fk-pointing-to-element-class column="group_id"/>
> >>> </collection-descriptor>
> >>> </class-descriptor>
> >>>
> >>> <class-descriptor
> >>> class="com.interlinkj.ac.Group"
> >>> table="GROUPS"
> >>> row-reader="com.interlinkj.db.GroupRowReader">
> >>> <field-descriptor
> >>> name="id"
> >>> column="id"
> >>> jdbc-type="INTEGER"
> >>> primarykey="true"
> >>> autoincrement="true"/>
> >>> <field-descriptor
> >>> name="name"
> >>> column="name"
> >>> jdbc-type="VARCHAR"
> >>> nullable="false"/>
> >>> <field-descriptor
> >>> name="description"
> >>> column="description"
> >>> jdbc-type="VARCHAR"
> >>> nullable="true"/>
> >>> <field-descriptor
> >>> name="type"
> >>> column="type"
> >>> jdbc-type="VARCHAR"
> >>> nullable="false"
> >>> conversion="com.interlinkj.db.GroupTypeConversion"/>
> >>> <collection-descriptor
> >>> name="users"
> >>> element-class-ref="com.interlinkj.ac.User"
> >>> indirection-table="USER_GROUP_LINK"
> >>> auto-delete="link"
> >>> auto-update="object"
> >>> auto-retrieve="true"
> >>> orderby="id"
> >>> sort="ASC"
> >>> >
> >>> <fk-pointing-to-this-class column="group_id"/>
> >>> <fk-pointing-to-element-class column="user_id"/>
> >>> </collection-descriptor>
> >>> </class-descriptor>
> >>>
> >>>:Test Data (for those not familiar with DBUnit, the element name is the
> >>
> >>table,
> >>
> >>>the attributes are the columns, and each element represents a row [in
> >>
> >>order]):
> >>
> >>><dataset>
> >>> <GROUPS id="1" type="Designer Group" name="Designer Group"
> >>>description="This is a designer group."/>
> >>> <GROUPS id="2" type="Data Entry Group" name="Data Entry Group"
> >>>description="This is a data entry group."/>
> >>> <USERS id="1" firstname="Bernard" lastname="Black"
> >>
> >>username="blblack"
> >>
> >>>credentials="jamjamjam"/>
> >>> <USERS id="2" firstname="Manny" lastname="Bianco" username="manny"
> >>>credentials="brilliant"/>
> >>> <USER_GROUP_LINK group_id="1" user_id="1"/>
> >>> <USER_GROUP_LINK group_id="2" user_id="2"/>
> >>></dataset>
> >>>
> >>>
> >>>:Stack Trace:
> >>>
> >>>java.lang.NullPointerException
> >>> at
> >>>
> >>
> >
>
org.apache.ojb.broker.accesslayer.MtoNCollectionPrefetcher.associateBatched(Unknown
> >
> >>>Source)
> >>> at
> >>>
> >>
> >
>
org.apache.ojb.broker.accesslayer.MtoNCollectionPrefetcher.prefetchRelationship(Unknown
> >
> >>>Source)
> >>> at
> >>>
> >>
> >>org.apache.ojb.broker.core.QueryReferenceBroker.performRetrievalTasks(Unknown
> >>
> >>>Source)
> >>> at
> >>>
> >>
> >>org.apache.ojb.broker.core.QueryReferenceBroker.getCollectionByQuery(Unknown
> >>Source)
> >>
> >>> at
> >>>
> >>
> >>org.apache.ojb.broker.core.QueryReferenceBroker.getCollectionByQuery(Unknown
> >>Source)
> >>
> >>> at
> >>>
> >>
> >>org.apache.ojb.broker.core.QueryReferenceBroker.getCollectionByQuery(Unknown
> >>Source)
> >>
> >>> at
> >>>org.apache.ojb.broker.core.QueryReferenceBroker.retrieveCollection(Unknown
> >>
> >>Source)
> >>
> >>> at
> >>>org.apache.ojb.broker.core.QueryReferenceBroker.retrieveCollections(Unknown
> >>
> >>Source)
> >>
> >>> at
> >>>org.apache.ojb.broker.accesslayer.RsIterator.getObjectFromResultSet(Unknown
> >>
> >>Source)
> >>
> >>> at org.apache.ojb.broker.accesslayer.RsIterator.next(Unknown
> >>
> >>Source)
> >>
> >>> at
> >>>org.apache.ojb.broker.core.PersistenceBrokerImpl.getObjectByQuery(Unknown
> >>
> >>Source)
> >>
> >>> at
> >>>
> >>
> >>org.apache.ojb.broker.core.DelegatingPersistenceBroker.getObjectByQuery(Unknown
> >>
> >>>Source)
> >>> at
> >>>
> >>
> >>org.apache.ojb.broker.core.DelegatingPersistenceBroker.getObjectByQuery(Unknown
> >>
> >>>Source)
> >>> at com.interlinkj.db.DatabaseManager.loadByFieldValue(Unknown
> >>
> >>Source)
> >>
> >>> at com.interlinkj.db.GroupManager.loadById(Unknown Source)
> >>> at
> >>
> >>com.interlinkj.db.TestGroupManager.testLoadWithIndividualUser(Unknown
> >>
> >>>Source)
> >>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> >>> at
> >>>
> >>
> >>sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> >>
> >>> at
> >>>
> >>
> >
>
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> >
> >>> at java.lang.reflect.Method.invoke(Method.java:585)
> >>> at junit.framework.TestCase.runTest(TestCase.java:154)
> >>> at junit.framework.TestCase.runBare(TestCase.java:127)
> >>>
> >>>
> >>>:Calling Code:
> >>>
> >>> Criteria crit = new Criteria();
> >>> crit.addEqualTo("id", new Integer(1));
> >>> Query q = newQuery(Group.class, crit);
> >>> broker = newPersistenceBroker(); //just a helper method to
> >>
> >>default
> >>
> >>>broker
> >>> Object tmp = broker.getObjectByQuery(q);
> >>>
> >>> //Null pointer before it gets here
> >>>
> >>> if(tmp == null){
> >>> throw new FindException(
> >>> getShortClassName(clazzToLoad) +
> >>> " with " +
> >>> fieldName +
> >>> " of " +
> >>> fieldValue +
> >>> " does not exist."
> >>> );
> >>> }
> >>> return (T)tmp;
> >>>
> >>>
> >>>
> >>>
> >>>------------------------------------------------------------
> >>>This email was sent from Netspace Webmail: http://www.netspace.net.au
> >>>
> >>>
> >>>---------------------------------------------------------------------
> >>>To unsubscribe, e-mail: [EMAIL PROTECTED]
> >>>For additional commands, e-mail: [EMAIL PROTECTED]
> >>>
> >>>
> >>
> >>---------------------------------------------------------------------
> >>To unsubscribe, e-mail: [EMAIL PROTECTED]
> >>For additional commands, e-mail: [EMAIL PROTECTED]
> >>
> >>
> >
> >
> >
> >
> >
> >
> > ------------------------------------------------------------
> > This email was sent from Netspace Webmail: http://www.netspace.net.au
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [EMAIL PROTECTED]
> > For additional commands, e-mail: [EMAIL PROTECTED]
> >
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>
------------------------------------------------------------
This email was sent from Netspace Webmail: http://www.netspace.net.au
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]