// Retrieve old value for field
smAttached.loadField(fieldNumber);
oldValue = smAttached.provideField(fieldNumber);
}
SCO sco;
if (oldValue == null || (oldValue != null && !(oldValue instanceof SCO)))
{
// Detached object didn't use wrapped field
if (NucleusLogger.JDO.isDebugEnabled())
{
NucleusLogger.JDO.debug(LOCALISER.msg("026029", StringUtils.toJVMIDString(smAttached.getObject()),
smAttached.getInternalObjectId(), mmd.getName()));
}
sco = SCOUtils.newSCOInstance(smAttached, mmd, mmd.getType(), null, null, false, false, false);
if (sco instanceof SCOContainer)
{
// Load any containers to avoid update issues
((SCOContainer)sco).load();
}
smAttached.replaceField(fieldNumber, sco, true);
}
else
{
// The field is already a SCO wrapper, so just copy the new values to it
sco = (SCO) oldValue;
}
if (cascadeAttach)
{
// Only trigger the cascade when required
if (copy)
{
// Attach copy of the SCO
sco.attachCopy(value);
}
else
{
// Attach SCO in-situ
// TODO This doesn't seem to handle any removal of things while detached
// Should be changed to do things like in attachCopy above.
if (sco instanceof Collection)
{
// Attach all PC elements of the collection
SCOUtils.attachForCollection(smAttached, ((Collection)value).toArray(),
SCOUtils.collectionHasElementsWithoutIdentity(mmd));
}
else if (sco instanceof Map)
{
// Attach all PC keys/values of the map
SCOUtils.attachForMap(smAttached, ((Map)value).entrySet(),
SCOUtils.mapHasKeysWithoutIdentity(mmd),
SCOUtils.mapHasValuesWithoutIdentity(mmd));
}
else
{
// Initialise the SCO with the new value
sco.initialise(value, false, false);
}
}
}
if (fieldsToAttach[fieldNumber] || !persistent)