KeyRegistry.getKeyRegistry(op.getExecutionContext()).registerParentKeyForOwnedObject(element, parentKey);
}
// Make sure that the element is persisted in the datastore (reachability)
final Object newOwner = op.getObject();
ExecutionContext ec = op.getExecutionContext();
boolean inserted = validateElementForWriting(ec, element, new FieldValues() {
public void fetchFields(ObjectProvider esm) {
// Find the (element) table storing the FK back to the owner
JavaTypeMapping externalFKMapping = elementTable.getExternalMapping(ownerMemberMetaData,
MappingConsumer.MAPPING_TYPE_EXTERNAL_FK);
if (externalFKMapping != null) {
// The element has an external FK mapping so set the value it needs to use in the INSERT
esm.setAssociatedValue(externalFKMapping, op.getObject());
}
if (relationType == RelationType.ONE_TO_MANY_BI) {
// TODO Move this into RelationshipManager
// Managed Relations : 1-N bidir, so make sure owner is correct at persist
Object currentOwner = esm.provideField(getFieldNumberInElementForBidirectional(esm));
if (currentOwner == null) {
// No owner, so correct it
NucleusLogger.PERSISTENCE.info(LOCALISER.msg("056037",
StringUtils.toJVMIDString(op.getObject()), ownerMemberMetaData.getFullFieldName(),
StringUtils.toJVMIDString(esm.getObject())));
esm.replaceFieldMakeDirty(getFieldNumberInElementForBidirectional(esm), newOwner);
}
else if (currentOwner != newOwner && op.getReferencedPC() == null) {
// Owner of the element is neither this container and not being attached
// Inconsistent owner, so throw exception
throw new NucleusUserException(LOCALISER.msg("056038",
StringUtils.toJVMIDString(op.getObject()), ownerMemberMetaData.getFullFieldName(),
StringUtils.toJVMIDString(esm.getObject()),
StringUtils.toJVMIDString(currentOwner)));
}
}
}
public void fetchNonLoadedFields(ObjectProvider sm) {}
public FetchPlan getFetchPlanForLoading() {return null;}
});
if (!inserted) {
// Element was already persistent so make sure the FK is in place
// TODO This is really "ManagedRelationships" so needs to go in RelationshipManager
ObjectProvider elementOP = ec.findObjectProvider(element);
if (relationType == RelationType.ONE_TO_MANY_BI) {
// Managed Relations : 1-N bidir, so update the owner of the element
elementOP.isLoaded(getFieldNumberInElementForBidirectional(elementOP)); // Ensure is loaded
Object oldOwner = elementOP.provideField(getFieldNumberInElementForBidirectional(elementOP));
if (oldOwner != newOwner) {
if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
NucleusLogger.PERSISTENCE.debug(LOCALISER.msg("055009", StringUtils.toJVMIDString(op.getObject()),
ownerMemberMetaData.getFullFieldName(), StringUtils.toJVMIDString(element)));
}
int relatedFieldNumber = getFieldNumberInElementForBidirectional(elementOP);
elementOP.replaceFieldMakeDirty(relatedFieldNumber, newOwner);
if (ec.getManageRelations()) {
// Managed Relationships - add the change we've made here to be analysed at flush
ec.getRelationshipManager(elementOP).relationChange(relatedFieldNumber, oldOwner, newOwner);
}
if (ec.isFlushing()) {
elementOP.flush();
}
}
return oldOwner != newOwner;
}