{
// Key is stored in the value and the value has changed so remove the old value
removeValue(sm, newKey, oldValue);
}
ObjectManager om = sm.getObjectManager();
final Object newOwner = sm.getObject();
if (om.getApiAdapter().isPersistent(newValue))
{
/*
* The new value is already persistent.
*
* "Put" the new value in the map by updating its owner and key
* fields to the appropriate values. This is done with the same
* methods the PC itself would use if the application code
* modified the fields. It should result in no actual database
* activity if the fields were already set to the right values.
*/
PersistenceCapable newValuePC = (PersistenceCapable)newValue;
if (om != om.getApiAdapter().getObjectManager(newValue))
{
throw new NucleusUserException(LOCALISER.msg("RDBMS.SCO.Map.WriteValudInvalidWithDifferentPM"), newValuePC.jdoGetObjectId());
}
StateManager vsm = om.findStateManager(newValue);
// Ensure the current owner field is loaded, and replace with new value
if (ownerFieldNumber >= 0)
{
om.getApiAdapter().isLoaded(vsm, ownerFieldNumber);
Object oldOwner = vsm.provideField(ownerFieldNumber);
vsm.setObjectField(newValuePC, ownerFieldNumber, oldOwner, newOwner);
}
else
{
updateValueFk(sm, newValue, newOwner);
}
// Ensure the current key field is loaded, and replace with new value
om.getApiAdapter().isLoaded(vsm, keyFieldNumber);
Object oldKey = vsm.provideField(keyFieldNumber);
vsm.setObjectField(newValuePC, keyFieldNumber, oldKey, newKey);
}
else
{
/*
* The new value is not yet persistent.
*
* Update its owner and key fields to the appropriate values and
* *then* make it persistent. Making the changes before DB
* insertion avoids an unnecessary UPDATE allows the owner
* and/or key fields to be non-nullable.
*/
om.persistObjectInternal(newValue, new FieldValues()
{
public void fetchFields(StateManager vsm)
{
if (ownerFieldNumber >= 0)
{
vsm.replaceField(ownerFieldNumber, newOwner, true);
}
vsm.replaceField(keyFieldNumber, newKey, true);
}
public void fetchNonLoadedFields(StateManager sm)
{
}
public FetchPlan getFetchPlanForLoading()
{
return null;
}
}, null, -1, StateManager.PC);
if (ownerFieldNumber < 0)
{
updateValueFk(sm, newValue, newOwner);
}
}
}
else
{
// Value is stored in the key
ObjectManager om = sm.getObjectManager();
PersistenceCapable pcNewKey = (PersistenceCapable)newKey;
final Object newOwner = sm.getObject();
if (om.getApiAdapter().isPersistent(pcNewKey))
{
/*
* The new key is already persistent.
*
* "Put" the new key in the map by updating its owner and value
* fields to the appropriate values. This is done with the same
* methods the PC itself would use if the application code
* modified the fields. It should result in no actual database
* activity if the fields were already set to the right values.
*/
if (om != om.getApiAdapter().getObjectManager(pcNewKey))
{
throw new NucleusUserException(LOCALISER.msg("056060"),
om.getApiAdapter().getIdForObject(pcNewKey));
}
StateManager vsm = om.findStateManager(pcNewKey);
// Ensure the current owner field is loaded, and replace with new key
if (ownerFieldNumber >= 0)
{
om.getApiAdapter().isLoaded(vsm, ownerFieldNumber);
Object oldOwner = vsm.provideField(ownerFieldNumber);
vsm.setObjectField(pcNewKey, ownerFieldNumber, oldOwner, newOwner);
}
else
{
updateKeyFk(sm, pcNewKey, newOwner);
}
// Ensure the current value field is loaded, and replace with new value
om.getApiAdapter().isLoaded(vsm, valueFieldNumber);
oldValue = vsm.provideField(valueFieldNumber); // TODO Should we update the local variable ?
vsm.setObjectField(pcNewKey, valueFieldNumber, oldValue, newValue);
}
else
{
/*
* The new key is not yet persistent.
*
* Update its owner and key fields to the appropriate values and
* *then* make it persistent. Making the changes before DB
* insertion avoids an unnecessary UPDATE allows the owner
* and/or key fields to be non-nullable.
*/
final Object newValueObj = newValue;
om.persistObjectInternal(newKey, new FieldValues()
{
public void fetchFields(StateManager vsm)
{
if (ownerFieldNumber >= 0)
{