Package org.datanucleus.store

Examples of org.datanucleus.store.ObjectProvider


                ExecutionContext ec = ownerSM.getExecutionContext();
                Iterator iter = c.iterator();
                while (iter.hasNext())
                {
                    Object pc = iter.next();
                    ObjectProvider objSM = ec.findObjectProvider(pc);
                    if (objSM == null)
                    {
                        objSM = ObjectProviderFactory.newForEmbedded(ec, pc, false, ownerSM, fieldNumber);
                    }
                }
View Full Code Here


     */
    protected void processPersistable(Object obj, AbstractMemberMetaData fmd)
    {
        // TODO Remove this reference to PersistenceCabable
        ApiAdapter api = sm.getExecutionContext().getApiAdapter();
        ObjectProvider sm = this.sm.getExecutionContext().findObjectProvider(obj);
        if (sm != null)
        {
            sm.runReachability(reachables);
        }
        else
        {
            if (NucleusLogger.PERSISTENCE.isDebugEnabled())
            {
View Full Code Here

                ExecutionContext ec = ownerSM.getExecutionContext();
                Iterator iter = c.iterator();
                while (iter.hasNext())
                {
                    Object pc = iter.next();
                    ObjectProvider objSM = ec.findObjectProvider(pc);
                    if (objSM == null)
                    {
                        objSM = ObjectProviderFactory.newForEmbedded(ec, pc, false, ownerSM,
                            ownerSM.getClassMetaData().getMetaDataForMember(fieldName).getAbsoluteFieldNumber());
                    }
View Full Code Here

        if (cmd.getIdentityType() == IdentityType.APPLICATION)
        {
            AbstractMemberMetaData mmd =
                cmd.getMetaDataForManagedMemberAtAbsolutePosition(cmd.getPKMemberPositions()[index]);
            ObjectProvider sm = null;
            if (ec != null)
            {
                sm = ec.findObjectProvider(value);
            }

            if (sm == null)
            {
                // Transient or detached maybe, so use reflection to get PK field values
                if (mmd instanceof FieldMetaData)
                {
                    return ClassUtils.getValueOfFieldByReflection(value, mmd.getName());
                }
                else
                {
                    return ClassUtils.getValueOfMethodByReflection(value,
                        ClassUtils.getJavaBeanGetterName(mmd.getName(), false), null);
                }
            }

            if (!mmd.isPrimaryKey())
            {
                // Make sure the field is loaded
                nucleusCtx.getApiAdapter().isLoaded(sm, mmd.getAbsoluteFieldNumber());
            }
            FieldManager fm = new SingleValueFieldManager();
            sm.provideFields(new int[] {mmd.getAbsoluteFieldNumber()}, fm);
            return fm.fetchObjectField(mmd.getAbsoluteFieldNumber());
        }
        else if (cmd.getIdentityType() == IdentityType.DATASTORE)
        {
            OID oid = (OID)nucleusCtx.getApiAdapter().getIdForObject(value);
View Full Code Here

        if (!api.isPersistable(value))
        {
            throw new NucleusException(LOCALISER.msg("041016", value.getClass(), value)).setFatal();
        }

        ObjectProvider valueSM = ec.findObjectProvider(value);

        try
        {
            ClassLoaderResolver clr = ec.getClassLoaderResolver();
            MappedStoreManager storeMgr = (MappedStoreManager)ec.getStoreManager();

            // Check if the field is attributed in the datastore
            boolean hasDatastoreAttributedPrimaryKeyValues = hasDatastoreAttributedPrimaryKeyValues(
                ec.getMetaDataManager(), storeMgr, clr);

            boolean inserted = false;
            if (ownerFieldNumber >= 0)
            {
                // Field mapping : is this field of the related object present in the datastore?
                inserted = storeMgr.isObjectInserted(valueSM, ownerFieldNumber);
            }
            else if (mmd == null)
            {
                // Identity mapping : is the object inserted far enough to be considered of this mapping type?
                inserted = storeMgr.isObjectInserted(valueSM, type);
            }

            if (valueSM != null)
            {
                if (ec.getApiAdapter().isDetached(value) && valueSM.getReferencedPC() != null && ownerSM != null && mmd != null)
                {
                    // Still detached but started attaching so replace the field with what will be the attached
                    // Note that we have "fmd != null" here hence omitting any M-N relations where this is a join table
                    // mapping
                    ownerSM.replaceFieldMakeDirty(ownerFieldNumber, valueSM.getReferencedPC());
                }

                if (valueSM.isWaitingToBeFlushedToDatastore())
                {
                    // Related object is not yet flushed to the datastore so flush it so we can set the FK
                    valueSM.flush();
                }
            }
            else
            {
                if (ec.getApiAdapter().isDetached(value))
                {
                    // Field value is detached and not yet started attaching, so attach
                    Object attachedValue = ec.persistObjectInternal(value, null, -1, ObjectProvider.PC);
                    if (attachedValue != value && ownerSM != null)
                    {
                        // Replace the field value if using copy-on-attach
                        ownerSM.replaceFieldMakeDirty(ownerFieldNumber, attachedValue);
                    }
                }
            }

            // we can execute this block when
            // 1) the pc has been inserted; OR
            // 2) is not in process of being inserted; OR
            // 3) is being inserted yet is inserted enough to use this mapping; OR
            // 4) the PC PK values are not attributed by the database and this mapping is for a PK field (compound identity)
            // 5) the value is the same object as we are inserting anyway and has its identity set
            if (inserted || !ec.isInserting(value) ||
                (!hasDatastoreAttributedPrimaryKeyValues && (this.mmd != null && this.mmd.isPrimaryKey())) ||
                (!hasDatastoreAttributedPrimaryKeyValues && ownerSM == valueSM && api.getIdForObject(value) != null))
            {
                // The PC is either already inserted, or inserted down to the level we need, or not inserted at all,
                // or the field is a PK and identity not attributed by the datastore

                // Object either already exists, or is not yet being inserted.
                id = api.getIdForObject(value);

                // Check if the PersistenceCapable exists in this datastore
                boolean requiresPersisting = false;
                if (ec.getApiAdapter().isDetached(value) && ownerSM != null)
                {
                    // Detached object so needs attaching
                    if (ownerSM.isInserting())
                    {
                        // Inserting other object, and this object is detached but if detached from this datastore
                        // we can just return the value now and attach later (in InsertRequest)
                        if (!ec.getNucleusContext().getPersistenceConfiguration().getBooleanProperty("datanucleus.attachSameDatastore"))
                        {
                            if (ec.getObjectFromCache(api.getIdForObject(value)) != null)
                            {
                                // Object is in cache so exists for this datastore, so no point checking
                            }
                            else
                            {
                                try
                                {
                                    Object obj = ec.findObject(api.getIdForObject(value), true, false,
                                        value.getClass().getName());
                                    if (obj != null)
                                    {
                                        // Make sure this object is not retained in cache etc
                                        ObjectProvider objSM = ec.findObjectProvider(obj);
                                        if (objSM != null)
                                        {
                                            ec.evictFromTransaction(objSM);
                                        }
                                        ec.removeObjectFromCache(api.getIdForObject(value));
                                    }
                                }
                                catch (NucleusObjectNotFoundException onfe)
                                {
                                    // Object doesnt yet exist
                                    requiresPersisting = true;
                                }
                            }
                        }
                    }
                    else
                    {
                        requiresPersisting = true;
                    }
                }
                else if (id == null)
                {
                    // Transient object, so we need to persist it
                    requiresPersisting = true;
                }
                else
                {
                    ExecutionContext pcEC = ec.getApiAdapter().getExecutionContext(value);
                    if (pcEC != null && ec != pcEC)
                    {
                        throw new NucleusUserException(LOCALISER.msg("041015"), id);
                    }
                }

                if (requiresPersisting)
                {
                    // PERSISTENCE-BY-REACHABILITY
                    // This PC object needs persisting (new or detached) to do the "set"
                    if (mmd != null && !mmd.isCascadePersist() && !ec.getApiAdapter().isDetached(value))
                    {
                        // Related PC object not persistent, but cant do cascade-persist so throw exception
                        if (NucleusLogger.PERSISTENCE.isDebugEnabled())
                        {
                            NucleusLogger.PERSISTENCE.debug(LOCALISER.msg("007006",
                                mmd.getFullFieldName()));
                        }
                        throw new ReachableObjectNotCascadedException(mmd.getFullFieldName(), value);
                    }

                    if (NucleusLogger.PERSISTENCE.isDebugEnabled())
                    {
                        NucleusLogger.PERSISTENCE.debug(LOCALISER.msg("007007",
                            mmd != null ? mmd.getFullFieldName() : null));
                    }

                    try
                    {
                        Object pcNew = ec.persistObjectInternal(value, null, -1, ObjectProvider.PC);
                        if (hasDatastoreAttributedPrimaryKeyValues)
                        {
                            ec.flushInternal(false);
                        }
                        id = api.getIdForObject(pcNew);
                        if (ec.getApiAdapter().isDetached(value) && ownerSM != null)
                        {
                            // Update any detached reference to refer to the attached variant
                            ownerSM.replaceFieldMakeDirty(ownerFieldNumber, pcNew);
                            int relationType = mmd.getRelationType(clr);
                            if (relationType == Relation.MANY_TO_ONE_BI)
                            {
                                // TODO Update the container to refer to the attached object
                                if (NucleusLogger.PERSISTENCE.isInfoEnabled())
                                {
                                    NucleusLogger.PERSISTENCE.info("PCMapping.setObject : object " + ownerSM.getInternalObjectId() +
                                        " has field " + ownerFieldNumber + " that is 1-N bidirectional." +
                                        " Have just attached the N side so should really update the reference in the 1 side collection" +
                                        " to refer to this attached object. Not yet implemented");
                                }
                            }
                            else if (relationType == Relation.ONE_TO_ONE_BI)
                            {
                                AbstractMemberMetaData[] relatedMmds = mmd.getRelatedMemberMetaData(clr);
                                // TODO Cater for more than 1 related field
                                ObjectProvider relatedSM = ec.findObjectProvider(pcNew);
                                relatedSM.replaceFieldMakeDirty(relatedMmds[0].getAbsoluteFieldNumber(), ownerSM.getObject());
                            }
                        }
                    }
                    catch (NotYetFlushedException e)
                    {
View Full Code Here

        int relationType = mmd.getRelationType(clr);
        if (pc != null)
        {
            if (relationType == Relation.ONE_TO_ONE_BI)
            {
                ObjectProvider otherSM = sm.getExecutionContext().findObjectProvider(pc);
                AbstractMemberMetaData relatedMmd = mmd.getRelatedMemberMetaDataForObject(clr, sm.getObject(), pc);
                Object relatedValue = otherSM.provideField(relatedMmd.getAbsoluteFieldNumber());
                if (relatedValue == null)
                {
                    // Managed Relations : Other side not set so update it in memory
                    if (NucleusLogger.PERSISTENCE.isDebugEnabled())
                    {
                        NucleusLogger.PERSISTENCE.debug(LOCALISER.msg("041018",
                            sm.toPrintableID(), mmd.getFullFieldName(),
                            StringUtils.toJVMIDString(pc), relatedMmd.getFullFieldName()));
                    }
                    otherSM.replaceField(relatedMmd.getAbsoluteFieldNumber(), sm.getObject());
                }
                else if (relatedValue != sm.getObject())
                {
                    // Managed Relations : Other side is inconsistent so throw exception
                    throw new NucleusUserException(
                        LOCALISER.msg("041020",
                            sm.toPrintableID(), mmd.getFullFieldName(),
                            StringUtils.toJVMIDString(pc),
                            StringUtils.toJVMIDString(relatedValue)));
                }
            }
            else if (relationType == Relation.MANY_TO_ONE_BI && relatedMmds[0].hasCollection())
            {
                // TODO Make sure we have this PC in the collection at the other side
                ObjectProvider otherSM = sm.getExecutionContext().findObjectProvider(pc);
                if (otherSM != null)
                {
                    // Managed Relations : add to the collection on the other side
                    Collection relatedColl = (Collection)otherSM.provideField(relatedMmds[0].getAbsoluteFieldNumber());
                    if (relatedColl != null && !(relatedColl instanceof SCOCollection))
                    {
                        // TODO Make sure the collection is a wrapper
                        boolean contained = relatedColl.contains(sm.getObject());
                        if (!contained)
                        {
                            NucleusLogger.PERSISTENCE.info(
                                LOCALISER.msg("041022",
                                sm.toPrintableID(), mmd.getFullFieldName(),
                                StringUtils.toJVMIDString(pc), relatedMmds[0].getFullFieldName()));
                            // TODO Enable this. CUrrently causes issues with
                            // PMImplTest, InheritanceStrategyTest, TCK "inheritance1.conf"
                            /*relatedColl.add(sm.getObject());*/
                        }
                    }
                }
            }
            else if (relationType == Relation.MANY_TO_ONE_UNI)
            {
                ObjectProvider otherSM = sm.getExecutionContext().findObjectProvider(pc);
                if (otherSM == null)
                {
                    // Related object is not yet persisted so persist it
                    Object other = sm.getExecutionContext().persistObjectInternal(pc, null, -1, ObjectProvider.PC);
                    otherSM = sm.getExecutionContext().findObjectProvider(other);
View Full Code Here

            return;
        }
        else
        {
            ObjectProvider otherSM = sm.getExecutionContext().findObjectProvider(pc);
            if (otherSM == null)
            {
                if (relationType == Relation.ONE_TO_ONE_BI || relationType == Relation.MANY_TO_ONE_BI ||
                    relationType == Relation.MANY_TO_ONE_UNI)
                {
View Full Code Here

            {
                // We're deleting the FK at this side so shouldnt be an issue
                AbstractMemberMetaData relatedMmd = mmd.getRelatedMemberMetaDataForObject(clr, sm.getObject(), pc);
                if (relatedMmd != null)
                {
                    ObjectProvider otherSM = ec.findObjectProvider(pc);
                    if (otherSM != null)
                    {
                        // Managed Relations : 1-1 bidir, so null out the object at the other
                        Object currentValue = otherSM.provideField(relatedMmd.getAbsoluteFieldNumber());
                        if (currentValue != null)
                        {
                            if (NucleusLogger.PERSISTENCE.isDebugEnabled())
                            {
                                NucleusLogger.PERSISTENCE.debug(LOCALISER.msg("041019",
                                    StringUtils.toJVMIDString(pc), relatedMmd.getFullFieldName(),
                                    sm.toPrintableID()));
                            }
                            otherSM.replaceFieldMakeDirty(relatedMmd.getAbsoluteFieldNumber(), null);

                            if (ec.getManageRelations())
                            {
                                otherSM.getExecutionContext().getRelationshipManager(otherSM).relationChange(
                                    relatedMmd.getAbsoluteFieldNumber(), sm.getObject(), null);
                            }
                        }
                    }
                }
            }
        }
        else if (relationType == Relation.ONE_TO_ONE_BI && mmd.getMappedBy() != null)
        {
            // 1-1 with FK at other side
            DatastoreClass relatedTable = storeMgr.getDatastoreClass(relatedMmds[0].getClassName(), clr);
            JavaTypeMapping relatedMapping = relatedTable.getMemberMapping(relatedMmds[0]);
            boolean isNullable = relatedMapping.isNullable();
            ObjectProvider otherSM = ec.findObjectProvider(pc);
            if (dependent)
            {
                if (isNullable)
                {
                    // Null out the FK in the datastore using a direct update (since we are deleting)
                    otherSM.replaceFieldMakeDirty(relatedMmds[0].getAbsoluteFieldNumber(), null);
                    otherSM.getExecutionContext().getStoreManager().getPersistenceHandler().updateObject(
                        otherSM, new int[]{relatedMmds[0].getAbsoluteFieldNumber()});
                }
                // Mark the other object for deletion
                ec.deleteObjectInternal(pc);
            }
            else if (!hasFK)
            {
                if (isNullable())
                {
                    Object currentRelatedValue = otherSM.provideField(relatedMmds[0].getAbsoluteFieldNumber());
                    if (currentRelatedValue != null)
                    {
                        // Null out the FK in the datastore using a direct update (since we are deleting)
                        otherSM.replaceFieldMakeDirty(relatedMmds[0].getAbsoluteFieldNumber(), null);
                        ec.getStoreManager().getPersistenceHandler().updateObject(
                            otherSM, new int[]{relatedMmds[0].getAbsoluteFieldNumber()});

                        // Managed Relations : 1-1 bidir, so null out the object at the other
                        if (ec.getManageRelations())
                        {
                            otherSM.getExecutionContext().getRelationshipManager(otherSM).relationChange(
                                relatedMmds[0].getAbsoluteFieldNumber(), sm.getObject(), null);
                        }
                    }
                }
                else
                {
                    // TODO Remove it
                }
            }
            else
            {
                // User has a FK defined (in MetaData) so let the datastore take care of it
            }
        }
        else if (relationType == Relation.MANY_TO_ONE_BI)
        {
            ObjectProvider otherSM = ec.findObjectProvider(pc);
            if (relatedMmds[0].getJoinMetaData() == null)
            {
                // N-1 with FK at this side
                if (otherSM.isDeleting())
                {
                    // Other object is being deleted too but this side has the FK so just delete this object
                }
                else
                {
                    // Other object is not being deleted so delete it if necessary
                    if (dependent)
                    {
                        if (isNullable())
                        {
                            // TODO Datastore nullability info can be unreliable so try to avoid this call
                            // Null out the FK in the datastore using a direct update (since we are deleting)
                            sm.replaceFieldMakeDirty(fieldNumber, null);
                            sm.getExecutionContext().getStoreManager().getPersistenceHandler().updateObject(sm, new int[]{fieldNumber});
                        }

                        if (ec.getApiAdapter().isDeleted(pc))
                        {
                            // Object is already tagged for deletion but we're deleting the FK so leave til flush()
                        }
                        else
                        {
                            // Mark the other object for deletion
                            ec.deleteObjectInternal(pc);
                        }
                    }
                    else
                    {
                        // Managed Relations : remove element from collection/map
                        if (relatedMmds[0].hasCollection())
                        {
                            // Only update the other side if not already being deleted
                            if (!ec.getApiAdapter().isDeleted(otherSM.getObject()) && !otherSM.isDeleting())
                            {
                                // Make sure the other object is updated in any caches
                                ec.markDirty(otherSM, false);
                                Collection otherColl = (Collection)otherSM.provideField(relatedMmds[0].getAbsoluteFieldNumber());
                                if (otherColl != null)
                                {
                                    if (ec.getManageRelations())
                                    {
                                        otherSM.getExecutionContext().getRelationshipManager(otherSM).relationRemove(
                                            relatedMmds[0].getAbsoluteFieldNumber(), sm.getObject());
                                    }
                                    // TODO Localise this message
                                    NucleusLogger.PERSISTENCE.debug("ManagedRelationships : delete of object causes removal from collection at " + relatedMmds[0].getFullFieldName());
                                    otherColl.remove(sm.getObject());
                                }
                            }
                        }
                        else if (relatedMmds[0].hasMap())
                        {
                            // TODO Cater for maps, but what is the key/value pair ?
                        }
                    }
                }
            }
            else
            {
                // N-1 with join table so no FK here so need to remove from Collection/Map first? (managed relations)
                if (dependent)
                {
                    // Mark the other object for deletion
                    ec.deleteObjectInternal(pc);
                }
                else
                {
                    // Managed Relations : remove element from collection/map
                    if (relatedMmds[0].hasCollection())
                    {
                        // Only update the other side if not already being deleted
                        if (!ec.getApiAdapter().isDeleted(otherSM.getObject()) && !otherSM.isDeleting())
                        {
                            // Make sure the other object is updated in any caches
                            ec.markDirty(otherSM, false);

                            // Make sure the other object has the collection loaded so does this change
                            otherSM.isLoaded(relatedMmds[0].getAbsoluteFieldNumber());
                            Collection otherColl = (Collection)otherSM.provideField(relatedMmds[0].getAbsoluteFieldNumber());
                            if (otherColl != null)
                            {
                                // TODO Localise this
                                NucleusLogger.PERSISTENCE.debug("ManagedRelationships : delete of object causes removal from collection at " + relatedMmds[0].getFullFieldName());
                                otherColl.remove(sm.getObject());
View Full Code Here

            validateElementForWriting(sm, element, null);

            if (relationType == Relation.ONE_TO_MANY_BI)
            {
                // TODO This is ManagedRelations - move into RelationshipManager
                ObjectProvider elementSM = sm.getExecutionContext().findObjectProvider(element);
                if (elementSM != null)
                {
                    AbstractMemberMetaData[] relatedMmds = ownerMemberMetaData.getRelatedMemberMetaData(clr);
                    // TODO Cater for more than 1 related field
                    Object elementOwner = elementSM.provideField(relatedMmds[0].getAbsoluteFieldNumber());
                    if (elementOwner == null)
                    {
                        // No owner, so correct it
                        NucleusLogger.PERSISTENCE.info(LOCALISER.msg("056037",
                            sm.toPrintableID(), ownerMemberMetaData.getFullFieldName(),
                            StringUtils.toJVMIDString(elementSM.getObject())));
                        elementSM.replaceField(relatedMmds[0].getAbsoluteFieldNumber(), sm.getObject());
                    }
                    else if (elementOwner != sm.getObject() && sm.getReferencedPC() == null)
                    {
                        // Owner of the element is neither this container nor being attached
                        // Inconsistent owner, so throw exception
                        throw new NucleusUserException(LOCALISER.msg("056038",
                            sm.toPrintableID(), ownerMemberMetaData.getFullFieldName(),
                            StringUtils.toJVMIDString(elementSM.getObject()),
                            StringUtils.toJVMIDString(elementOwner)));
                    }
                }
            }
View Full Code Here

                            Object element = iter.next();
                            if (ownerSM.getLifecycleState().isDeleted)
                            {
                                // Deleting the owner, so register the element to reset its owner
                                ownerSM.getObjectManager().removeObjectFromLevel2Cache(ownerSM.getObjectManager().getApiAdapter().getIdForObject(element));
                                ObjectProvider elementSM = ownerSM.getObjectManager().findObjectProvider(element);
                                if (relationType == Relation.ONE_TO_MANY_BI)
                                {
                                    ec.getRelationshipManager(elementSM).relationChange(relatedMmd.getAbsoluteFieldNumber(), ownerSM.getObject(), null);
                                }
                                else if (relationType == Relation.MANY_TO_MANY_BI)
                                {
                                    ec.getRelationshipManager(elementSM).relationRemove(relatedMmd.getAbsoluteFieldNumber(), ownerSM.getObject());
                                }
                            }
                            else
                            {
                                // Remove the element
                                changes.add(new RelationChange(ChangeType.REMOVE_OBJECT, element));
                            }
                        }
                    }
                    else
                    {
                        // Remove some and add some
                        Iterator newIter = ((Collection)newValue).iterator();
                        while (newIter.hasNext())
                        {
                            Object newElem = newIter.next();
                            Iterator oldIter = ((Collection)oldValue).iterator();
                            boolean alreadyExists = false;
                            while (oldIter.hasNext())
                            {
                                Object oldElem = oldIter.next();
                                if (newElem == oldElem)
                                {
                                    alreadyExists = true;
                                    break;
                                }
                            }
                            if (!alreadyExists)
                            {
                                ObjectProvider elemSM = ownerSM.getObjectManager().findObjectProvider(newElem);
                                if (elemSM != null)
                                {
                                    AbstractMemberMetaData elemMmd = mmd.getRelatedMemberMetaData(ownerSM.getObjectManager().getClassLoaderResolver())[0];
                                    Object oldOwner = elemSM.provideField(elemMmd.getAbsoluteFieldNumber());
                                    if (!elemSM.isFieldLoaded(elemMmd.getAbsoluteFieldNumber()))
                                    {
                                        elemSM.loadField(elemMmd.getAbsoluteFieldNumber());
                                    }
                                    if (oldOwner != null)
                                    {
                                        // Remove from old owner collection
                                        ObjectProvider oldOwnerSM = ownerSM.getObjectManager().findObjectProvider(oldOwner);
                                        if (oldOwnerSM != null)
                                        {
                                            ec.getRelationshipManager(oldOwnerSM).relationRemove(fieldNumber, newElem);
                                        }
                                    }
View Full Code Here

TOP

Related Classes of org.datanucleus.store.ObjectProvider

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.