protected void associateBatched(Collection owners, Collection children, Collection mToNImplementors)
    {
        CollectionDescriptor cds = getCollectionDescriptor();
        PersistentField field = cds.getPersistentField();
        PersistenceBroker pb = getBroker();
        Class ownerTopLevelClass = pb.getTopLevelClass(getOwnerClassDescriptor().getClassOfObject());
        Class childTopLevelClass = pb.getTopLevelClass(getItemClassDescriptor().getClassOfObject());
        Class collectionClass = cds.getCollectionClass(); // this collection type will be used:
        HashMap childMap = new HashMap();
        HashMap ownerIdsToLists = new HashMap();
        FieldConversion[] ownerFc = getPkFieldConversion(getOwnerClassDescriptor()); 
        FieldConversion[] childFc = getPkFieldConversion(getItemClassDescriptor());  

        // initialize the owner list map
        for (Iterator it = owners.iterator(); it.hasNext();)
        {
            Object owner = it.next();
            Identity oid = pb.serviceIdentity().buildIdentity(owner);
            ownerIdsToLists.put(oid, new ArrayList());
        }

        // build the children map
        for (Iterator it = children.iterator(); it.hasNext();)
        {
            Object child = it.next();
            Identity oid = pb.serviceIdentity().buildIdentity(child);
            childMap.put(oid, child);
        }

        int ownerPkLen = getOwnerClassDescriptor().getPkFields().length;
        int childPkLen = getItemClassDescriptor().getPkFields().length;
        Object[] ownerPk = new Object[ownerPkLen];
        Object[] childPk = new Object[childPkLen];

        // build list of children based on m:n implementors
        for (Iterator it = mToNImplementors.iterator(); it.hasNext();)
        {
            Object[] mToN = (Object[]) it.next();
            System.arraycopy(mToN, 0, ownerPk, 0, ownerPkLen);
            System.arraycopy(mToN, ownerPkLen, childPk, 0, childPkLen);

            // BRJ: apply the FieldConversions, OJB296
            ownerPk = convert(ownerFc, ownerPk);
            childPk = convert(childFc, childPk);

            Identity ownerId = pb.serviceIdentity().buildIdentity(null, ownerTopLevelClass, ownerPk);
            Identity childId = pb.serviceIdentity().buildIdentity(null, childTopLevelClass, childPk);

            // Identities may not be equal due to type-mismatch
            Collection list = (Collection) ownerIdsToLists.get(ownerId);
            Object child = childMap.get(childId);
            list.add(child);
        }

        // connect children list to owners
        for (Iterator it = owners.iterator(); it.hasNext();)
        {
            Object result;
            Object owner = it.next();
            Identity ownerId = pb.serviceIdentity().buildIdentity(owner);

            List list = (List) ownerIdsToLists.get(ownerId);

            if ((collectionClass == null) && field.getType().isArray())
            {
                int length = list.size();
                Class itemtype = field.getType().getComponentType();

                result = Array.newInstance(itemtype, length);

                for (int j = 0; j < length; j++)
                {
                    Array.set(result, j, list.get(j));
                }
            }
            else
            {
                ManageableCollection col = createCollection(cds, collectionClass);

                for (Iterator it2 = list.iterator(); it2.hasNext();)
                {
                    col.ojbAdd(it2.next());
                }
                result = col;
            }

            Object value = field.get(owner);
            if ((value instanceof CollectionProxyDefaultImpl) && (result instanceof Collection))
            {
                ((CollectionProxyDefaultImpl) value).setData((Collection) result);
            }
            else
            {
                field.set(owner, result);
            }
        }

    }
protected void associateBatched ( Collection owners , Collection children , Collection mToNImplementors ) { CollectionDescriptor cds = getCollectionDescriptor ( ) ; PersistentField field = cds . getPersistentField ( ) ; PersistenceBroker pb = getBroker ( ) ; Class ownerTopLevelClass = pb . getTopLevelClass ( getOwnerClassDescriptor ( ) . getClassOfObject ( ) ) ; Class childTopLevelClass = pb . getTopLevelClass ( getItemClassDescriptor ( ) . getClassOfObject ( ) ) ; Class collectionClass = cds . getCollectionClass ( ) ; HashMap childMap = new HashMap ( ) ; HashMap ownerIdsToLists = new HashMap ( ) ; FieldConversion [ ] ownerFc = getPkFieldConversion ( getOwnerClassDescriptor ( ) ) ; FieldConversion [ ] childFc = getPkFieldConversion ( getItemClassDescriptor ( ) ) ; for ( Iterator it = owners . iterator ( ) ; it . hasNext ( ) ; ) { Object owner = it . next ( ) ; Identity oid = pb . serviceIdentity ( ) . buildIdentity ( owner ) ; ownerIdsToLists . put ( oid , new ArrayList ( ) ) ; } for ( Iterator it = children . iterator ( ) ; it . hasNext ( ) ; ) { Object child = it . next ( ) ; Identity oid = pb . serviceIdentity ( ) . buildIdentity ( child ) ; childMap . put ( oid , child ) ; } int ownerPkLen = getOwnerClassDescriptor ( ) . getPkFields ( ) . length ; int childPkLen = getItemClassDescriptor ( ) . getPkFields ( ) . length ; Object [ ] ownerPk = new Object [ ownerPkLen ] ; Object [ ] childPk = new Object [ childPkLen ] ; for ( Iterator it = mToNImplementors . iterator ( ) ; it . hasNext ( ) ; ) { Object [ ] mToN = ( Object [ ] ) it . next ( ) ; System . arraycopy ( mToN , 0 , ownerPk , 0 , ownerPkLen ) ; System . arraycopy ( mToN , ownerPkLen , childPk , 0 , childPkLen ) ; ownerPk = convert ( ownerFc , ownerPk ) ; childPk = convert ( childFc , childPk ) ; Identity ownerId = pb . serviceIdentity ( ) . buildIdentity ( null , ownerTopLevelClass , ownerPk ) ; Identity childId = pb . serviceIdentity ( ) . buildIdentity ( null , childTopLevelClass , childPk ) ; Collection list = ( Collection ) ownerIdsToLists . get ( ownerId ) ; Object child = childMap . get ( childId ) ; list . add ( child ) ; } for ( Iterator it = owners . iterator ( ) ; it . hasNext ( ) ; ) { Object result ; Object owner = it . next ( ) ; Identity ownerId = pb . serviceIdentity ( ) . buildIdentity ( owner ) ; List list = ( List ) ownerIdsToLists . get ( ownerId ) ; if ( ( collectionClass == null ) && field . getType ( ) . isArray ( ) ) { int length = list . size ( ) ; Class itemtype = field . getType ( ) . getComponentType ( ) ; result = Array . newInstance ( itemtype , length ) ; for ( int j = 0 ; j < length ; j ++ ) { Array . set ( result , j , list . get ( j ) ) ; } } else { ManageableCollection col = createCollection ( cds , collectionClass ) ; for ( Iterator it2 = list . iterator ( ) ; it2 . hasNext ( ) ; ) { col . ojbAdd ( it2 . next ( ) ) ; } result = col ; } Object value = field . get ( owner ) ; if ( ( value instanceof CollectionProxyDefaultImpl ) && ( result instanceof Collection ) ) { ( ( CollectionProxyDefaultImpl ) value ) . setData ( ( Collection ) result ) ; } else { field . set ( owner , result ) ; } } }
associate the batched Children with their owner object loop over children
<br><br>
BRJ: There is a potential problem with the type of the pks used to build the Identities.
When creating an Identity for the owner, the type of pk is defined by the instvars
representing the pk. When creating the Identity based on the mToNImplementor the
type of the pk is defined by the jdbc-type of field-descriptor of the referenced class.
This type mismatch results in Identities not being equal.
Integer[] {10,20,30} is not equal Long[] {10,20,30}
<br><br>
This problem is documented in defect OJB296.
The conversion of the keys of the mToNImplementor should solve this problem.