* @param ownerSM the owner StateManager
* @param ownerFieldNumber the owner absolute field number
*/
public void setObject(ObjectManager om, Object ps, int[] pos, Object value, StateManager ownerSM, int ownerFieldNumber)
{
ClassLoaderResolver clr = om.getClassLoaderResolver();
ApiAdapter api = om.getApiAdapter();
int n = 0;
boolean foundClassAssignableFromValue = false;
NotYetFlushedException notYetFlushed = null;
if (value != null)
{
if (!om.isInserting(value))
{
// Object either already exists, or is not yet being inserted.
Object id = api.getIdForObject(value);
// Check if the PersistenceCapable exists in this datastore
boolean requiresPersisting = false;
if (om.getApiAdapter().isDetached(value) && ownerSM != null)
{
// Detached object that needs attaching (or persisting if detached from a different datastore)
requiresPersisting = true;
}
else if (id == null)
{
// Transient object, so we need to persist it
requiresPersisting = true;
}
else
{
ObjectManager valueOM = ObjectManagerHelper.getObjectManager(value);
if (valueOM != null && om != valueOM)
{
throw new JPOXUserException(LOCALISER.msg("041015"), id);
}
}
if (requiresPersisting)
{
// The object is either not yet persistent or is detached and so needs attaching
Object pcNew = om.persistObjectInternal(value, null, null, -1, StateManager.PC);
om.flushInternal(false);
id = api.getIdForObject(pcNew);
if (om.getApiAdapter().isDetached(value) && ownerSM != null)
{
// Update any detached reference to refer to the attached variant
ownerSM.replaceField(ownerFieldNumber, pcNew, true);
int relationType = fmd.getRelationType(clr);
if (relationType == Relation.ONE_TO_ONE_BI)
{
StateManager relatedSM = om.findStateManager(pcNew);
AbstractMemberMetaData[] relatedMmds = fmd.getRelatedMemberMetaData(clr);
// TODO Allow for multiple related fields
relatedSM.replaceField(relatedMmds[0].getAbsoluteFieldNumber(), ownerSM.getObject(), true);
}
else if (relationType == Relation.MANY_TO_ONE_BI)
{
// TODO Update the container element with the attached variant
if (JPOXLogger.PERSISTENCE.isInfoEnabled())
{
JPOXLogger.PERSISTENCE.info("PCMapping.setObject : object " + ownerSM.getInternalObjectId() +
" has field " + ownerFieldNumber +
" that is 1-N bidirectional - should really update the reference in the relation. Not yet supported");
}
}
}
}
if (getNumberOfDatastoreFields() <= 0)
{
// If the field doesnt map to any datastore fields, omit the set process
return;
}
}
}
Class type = null;
StateManager sm = null;
if (value != null)
{
sm = om.findStateManager(value);
}
try
{
if (pos == null)
{
return;
}
if (sm != null)
{
sm.setStoringPC();
}
MetaDataManager mmgr = om.getStoreManager().getOMFContext().getMetaDataManager();
boolean isPersistentInterface = mmgr.getMetaDataForInterface(clr.classForName(getType()), clr) != null;
if (isPersistentInterface)
{
// Field is declared as a "persistent-interface" type so all impls of that type should match
type = clr.classForName(getType());
}
else if (fmd != null && fmd.getFieldTypes() != null && fmd.getFieldTypes().length == 1)
{
isPersistentInterface = mmgr.getMetaDataForInterface(clr.classForName(fmd.getFieldTypes()[0]), clr) != null;
if (isPersistentInterface)
{
// Field is declared as interface and accepts "persistent-interface" value, so all impls should match
type = clr.classForName(fmd.getFieldTypes()[0]);
}
}
for (int i=0; i<javaTypeMappings.length; i++)
{
if (n >=pos.length)
{
//this means we store all implementations to the same columns, so we reset the index
n = 0;
}
int[] posMapping;
if (javaTypeMappings[i].getReferenceMapping() != null)
{
posMapping = new int[javaTypeMappings[i].getReferenceMapping().getNumberOfDatastoreFields()];
}
else
{
posMapping = new int[javaTypeMappings[i].getNumberOfDatastoreFields()];
}
for (int j=0; j<posMapping.length; j++)
{
posMapping[j] = pos[n++];
}
try
{
if (!isPersistentInterface)
{
// Normal interface
type = clr.classForName(javaTypeMappings[i].getType());
}
if (value != null && type.isAssignableFrom(value.getClass()))
{
foundClassAssignableFromValue = true;
javaTypeMappings[i].setObject(om, ps, posMapping, value);