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 ol...@ppi.de on 2004/09/03 13:08:00 UTC
non-equal Identities for primary-key fields with FieldConversion
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: ojb-user-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-user-help@db.apache.org
Re: non-equal Identities for primary-key fields with FieldConversion
Posted by Jakob Braeuchi <jb...@gmx.ch>.
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);
> }
>
> oliver.matz@ppi.de 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: ojb-user-unsubscribe@db.apache.org
>> For additional commands, e-mail: ojb-user-help@db.apache.org
>>
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: ojb-user-unsubscribe@db.apache.org
> For additional commands, e-mail: ojb-user-help@db.apache.org
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-user-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-user-help@db.apache.org
Re: non-equal Identities for primary-key fields with FieldConversion
Posted by "Ludovic Maitre (POP - Factory Part)" <lm...@factory-part.com>.
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);
}
oliver.matz@ppi.de 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: ojb-user-unsubscribe@db.apache.org
>For additional commands, e-mail: ojb-user-help@db.apache.org
>
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-user-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-user-help@db.apache.org