hi oli, ludovic,
could you please post the part of the repository that causes the problem ?
as i mentioned in http://nagoya.apache.org/scarab/issues/id/OJB296 it's not sufficient to use the field-conversion of only one class. imo the conversion should be done on both fk-sets:
.... Object[] mToN = (Object[]) it.next(); System.arraycopy(mToN, 0, ownerPk, 0, ownerPkLen); System.arraycopy(mToN, ownerPkLen, childPk, 0, childPkLen);
ownerPk = convert_keys(ownerPk, ownerCld); childPk = convert_keys(childPk, childCld);
Identity ownerId = idFactory.buildIdentity(null, ownerTopLevelClass, ownerPk); Identity childId = idFactory.buildIdentity(null, childTopLevelClass, childPk); ....
what do you think about ?
jakob
Ludovic Maitre (POP - Factory Part) schrieb:
hello,
I have the same problem and use the following patch. Tell me if this help (and if this is safe!):
[line added are precede by LMA]
protected void associateBatched(Collection owners, Collection children, Collection mToNImplementors)
{
CollectionDescriptor cds = getCollectionDescriptor();
PersistentField field = cds.getPersistentField();
//LMA: Use a field conversion if necessary
//[Solve the potential problem described above]
FieldConversion fc = cds.getClassDescriptor().getPrimaryKey().getFieldConversion();
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();
// initialize the owner list map for (Iterator it = owners.iterator(); it.hasNext();) { Object owner = it.next(); ownerIdsToLists.put(new Identity(owner, pb), new ArrayList()); }
// build the children map for (Iterator it = children.iterator(); it.hasNext();) { Object child = it.next(); childMap.put(new Identity(child, pb), 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();
//LMA: Use the field conversion if it exist. We assume that the pk of the 2 objects are of the same type.
//[solve the potential problem described by BRJ]
if (fc!=null)
for (int i=0;i<mToN.length;i++)
mToN[i]=fc.sqlToJava(mToN[i]);
System.arraycopy(mToN, 0, ownerPk, 0, ownerPkLen);
System.arraycopy(mToN, ownerPkLen, childPk, 0, childPkLen);
Identity ownerId = new Identity(null, ownerTopLevelClass, ownerPk);
Identity childId = new Identity(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); }
[EMAIL PROTECTED] wrote:
Hello,
I am currently porting our application from OJB 1.0.0rc4 to OJB 1.0.0
A new problem has been introduced since then in MtoNCollectionPrefetcher.associateBatched, as Jakob points out in this source's javadoc:
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. <br>
* Integer[] {10,20,30} is not equal Long[] {10,20,30}
In my application, I use primary keys of type Long mapped to BigDecimal. The issue then results in the stacktrace below.
java.lang.NullPointerException
at
org.apache.ojb.broker.accesslayer.MtoNCollectionPrefetcher.associateBatched(
MtoNCollectionPrefetcher.java:408)
at
org.apache.ojb.broker.accesslayer.MtoNCollectionPrefetcher.prefetchRelations
hip(MtoNCollectionPrefetcher.java:94)
at
org.apache.ojb.broker.core.QueryReferenceBroker$PBPrefetchingListener.prefet
ch(QueryReferenceBroker.java:873)
at
org.apache.ojb.broker.core.QueryReferenceBroker$PBCollectionProxyListener.be
foreLoading(QueryReferenceBroker.java:930)
at
org.apache.ojb.broker.core.proxy.CollectionProxyDefaultImpl.beforeLoading(Co
llectionProxyDefaultImpl.java:182)
at
org.apache.ojb.broker.core.proxy.CollectionProxyDefaultImpl.getData(Collecti
onProxyDefaultImpl.java:425)
at
org.apache.ojb.broker.core.proxy.CollectionProxyDefaultImpl.toArray(Collecti
onProxyDefaultImpl.java:260)
at
de.ppi.neuwerk.repman.persistent.ojb.AuditOjb.getCreatedNodes(AuditOjb.java:
157)
With some effort, I tried also current CVS head, and the problem is still there.
Any ideas for a workaround? I wonder if anybody else has this problem?! I cannot image that we are the only ones who have primary-key fields with FieldConversion and who use m:n-Collections.
Best regards, Olli
P.S. I am committer myself, and I apologize for my long absence from active
participation.
--------------------------------------------------------------------- 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]
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
