A programmer at my side found a problem when storing objects that have collection with auto-update='true' or auto-update='link', with proxy='true'. The problem appear be the following piece of PerfistenceBrokerImpl.java:

private void storeAndLinkOneToMany(boolean linkOnly, Object obj, CollectionDescriptor cod, Object referencedObjects, boolean insert)
{
if(referencedObjects == null)
{
return;
}
/*
Only make sense to perform (link or/and store) real referenced objects
or materialized collection proxy objects, because on unmaterialized collection
nothing has changed.


- if the collection is a collectionproxy and it's not already loaded
no need to perform an update on the referenced objects
- on insert we link and insert the referenced objects, because the proxy
collection maybe "inherited" from the object before the PK was replaced
*/
if(insert || !(referencedObjects instanceof CollectionProxyDefaultImpl
&& !((CollectionProxyDefaultImpl) referencedObjects).isLoaded()))
{
Iterator it = getCollectionIterator(cod, referencedObjects);
Object refObj;
while(it.hasNext())
{
refObj = it.next();
// set FK in refObj if it is materialized
if(ProxyHelper.isMaterialized(refObj))
{
ClassDescriptor refCld = getClassDescriptor(ProxyHelper.getRealClass(refObj));
link(refObj, refCld, cod, obj, insert);
// if enabled cascade store and not only link, store the refObj
if(!linkOnly && cod.getCascadingStore() == CollectionDescriptor.CASCADE_OBJECT)
{
store(refObj);
}
}
}
}
}


As specified in link method javadoc, the refObj must be a real object (no proxies allowed). So the method throws exception. Changing the code to the following will work fine:

private void storeAndLinkOneToMany(boolean linkOnly, Object obj, CollectionDescriptor cod, Object referencedObjects, boolean insert)
{
if(referencedObjects == null)
{
return;
}
/*
Only make sense to perform (link or/and store) real referenced objects
or materialized collection proxy objects, because on unmaterialized collection
nothing has changed.


- if the collection is a collectionproxy and it's not already loaded
no need to perform an update on the referenced objects
- on insert we link and insert the referenced objects, because the proxy
collection maybe "inherited" from the object before the PK was replaced
*/
if(insert || !(referencedObjects instanceof CollectionProxyDefaultImpl
&& !((CollectionProxyDefaultImpl) referencedObjects).isLoaded()))
{
Iterator it = getCollectionIterator(cod, referencedObjects);
Object refObj;
while(it.hasNext())
{
refObj = it.next();
// set FK in refObj if it is materialized
if(ProxyHelper.isMaterialized(refObj))
{
if(ProxyHelper.isProxy(refObj)) {
refObj = ProxyHelper.getRealObject(refObj);
}


ClassDescriptor refCld = getClassDescriptor(ProxyHelper.getRealClass(refObj));
link(refObj, refCld, cod, obj, insert);
// if enabled cascade store and not only link, store the refObj
if(!linkOnly && cod.getCascadingStore() == CollectionDescriptor.CASCADE_OBJECT)
{
store(refObj);
}
}
}
}
}



Could someone confirm, and if possible, fix this in CVS HEAD?


Thanks,

Edson Richter

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to