Hello Armin,

This is tried. The code is good but only for updating selected fields not the reference objects (foreign keys and collections).
In fact, if we add the necessary code to fetch also the object references descriptors, the collection descriptors, the corresponding class descriptors, the anonymous fields corresponding to the object references descriptors... this become heavy. As i have understand the update method in OJB 1.1, it operate only on fields also, isn't it ? The "hasMultiMappedReference" at the end of the update method is for fetching somethink like a super class no ? It isn't for fetching (and filtering) the objects reference descriptors to update ?
Regards,
Ludo


Armin Waibel wrote:

Hi Ludo,

if "enableChangePerThread" is set true, your workaround should be valid.

The only drawback is the
> DescriptorRepository dr = manager.copyOfGlobalRepository();
call. If you have thousands of objects this method is costly (serialization of the DescriptorRepository instance).


Think to make it faster (but more complex) you can try to use a temporary DescriptorRepository instance with temp ClassDescriptor (not tested, only suggestion, does not work when using multiple joined table):

Seems to be complex, but should be faster than serialize the whole global DescriptorRepository on each method call.

public void update(Object target, String[] fieldsToUpdate)
{
DescriptorRepository temp = createTempRepositoryFor(
manager.getRepository().getDescriptorFor(target.getClass()), fieldsToUpdate);
manager.setDescriptor(temp);
PersistenceBroker broker = getBroker();
try
{
/*
now we can store the object to update
*/
//...
broker.beginTransaction();
broker.store(target);
broker.commitTransaction();
//... cleanup broker, exception handling
}
finally
{
manager.setDescriptor(null);
}
}


private DescriptorRepository createTempRepositoryFor(ClassDescriptor target, String[] fieldsToUpdate)
{
DescriptorRepository temp = new DescriptorRepository();
ClassDescriptor cld = new ClassDescriptor(temp);
temp.setClassDescriptor(cld);
// if an schema was used this method need more tweak to resolve table name
cld.setTableName(target.getFullTableName());
FieldDescriptor[] fields = getFieldsToUpdate(cld, fieldsToUpdate);
for(int i = 0; i < fields.length; i++)
{
FieldDescriptor field = fields[i];
cld.addFieldDescriptor(field);
}
return temp;
}



private FieldDescriptor[] getFieldsToUpdate(ClassDescriptor target, String[] fieldsToUpdate)
{
ArrayList result = new ArrayList();
FieldDescriptor[] fields = target.getFieldDescriptions();
for(int i = 0; i < fieldsToUpdate.length; i++)
{
String fieldName = fieldsToUpdate[i];
for(int k = 0; k < fields.length; k++)
{
FieldDescriptor field = fields[k];


if(field.getPersistentField().getName().equalsIgnoreCase(fieldName))
{
// make deep copy of used field
result.add(SerializationUtils.clone(field));
break;
}
}
}
if(fieldsToUpdate.length != result.size())
{
// throw exception, not all fields could be found
}
return (FieldDescriptor[]) result.toArray(new FieldDescriptor[result.size()]);
}


regards,
Armin




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



Reply via email to