We have experienced a serious performance defect in
org.apache.ojb.broker.accesslayer.ReferencePrefetcher
in rc5 with a reference-descriptor with auto-retrieve="true"
In our case we have a resultset with 450 records with
a reference-descriptor loading 450 related objects.
ReferencePrefetcher.associateBatched instansiated over
100,000 Identity objects and used several seconds CPU time.
No surprice if you look at the code, this problem will grow
exponentially with number of returned objects:
protected void associateBatched(Collection owners, Collection children) {
...
for (Iterator it = owners.iterator(); it.hasNext(); )
{
owner = it.next();
fkValues = ord.getForeignKeyValues(owner,cld);
if (isNull(fkValues))
{
field.set(owner, null);
continue;
}
id = new Identity(null, topLevelClass, fkValues);
for (Iterator it2 = children.iterator(); it2.hasNext(); )
{
relatedObject = it2.next();
id2 = new Identity(relatedObject, pb);
if (id.equals(id2))
{
field.set(owner, relatedObject);
break;
}
}
}
}
Here is my fixed version, but I know too little about OJB internals to be
sure if this is the best solution. If the entries in the children
collection contains no duplicates it will propably be better to make
a hash of them instead.
protected void associateBatched(Collection owners, Collection children) {
...
HashMap ownerHash = new HashMap();
for (Iterator it = owners.iterator(); it.hasNext();) {
owner = it.next();
fkValues = ord.getForeignKeyValues(owner, cld);
if (isNull(fkValues)) {
field.set(owner, null);
continue;
}
id = new Identity(null, topLevelClass, fkValues);
List ownerList = (List) ownerHash.get(id);
if (ownerList == null) {
ownerList = new ArrayList();
ownerHash.put(id, ownerList);
}
ownerList.add(owner);
}
for (Iterator it2 = children.iterator(); it2.hasNext();) {
relatedObject = it2.next();
id = new Identity(relatedObject, pb);
List ownerList = (List) ownerHash.get(id);
if (ownerList != null) {
for (int i = 0; i < ownerList.size(); i++) {
field.set(ownerList.get(i), relatedObject);
}
} else {
// Should not happen ????
}
}
}
It looks like PlainPrefetcher.associateBatched() has the same behaviour.
Anybody who knows what the SqlInLimit should be set to for Oracle ?
--
Best regards Jan Magne HestÃs
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]