Search in sources :

Example 21 with NucleusObjectNotFoundException

use of org.datanucleus.exceptions.NucleusObjectNotFoundException in project datanucleus-core by datanucleus.

the class ReachabilityAtCommitHandler method execute.

/**
 * Method to perform the "persistence-by-reachability" at commit.
 */
public void execute() {
    try {
        this.executing = true;
        if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
            NucleusLogger.PERSISTENCE.debug(Localiser.msg("010032"));
        }
        // from makePersistent in this txn, or enlisted existing objects) then run reachability checks
        if (!persistedIds.isEmpty() && !flushedNewIds.isEmpty()) {
            Set currentReachables = new HashSet();
            // Run "reachability" on all known persistent objects for this txn
            Object[] ids = persistedIds.toArray();
            Set objectNotFound = new HashSet();
            for (int i = 0; i < ids.length; i++) {
                if (!deletedIds.contains(ids[i])) {
                    if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
                        NucleusLogger.PERSISTENCE.debug("Performing reachability algorithm on object with id \"" + ids[i] + "\"");
                    }
                    try {
                        ObjectProvider op = ec.findObjectProvider(ec.findObject(ids[i], true, true, null));
                        if (!op.isDeleted() && !currentReachables.contains(ids[i])) {
                            // Make sure all of its relation fields are loaded before continuing. Is this necessary, since its enlisted?
                            op.loadUnloadedRelationFields();
                            // Add this object id since not yet reached
                            if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
                                NucleusLogger.PERSISTENCE.debug(Localiser.msg("007000", StringUtils.toJVMIDString(op.getObject()), ids[i], op.getLifecycleState()));
                            }
                            currentReachables.add(ids[i]);
                            // Go through all relation fields using ReachabilityFieldManager
                            ReachabilityFieldManager pcFM = new ReachabilityFieldManager(op, currentReachables);
                            int[] relationFieldNums = op.getClassMetaData().getRelationMemberPositions(ec.getClassLoaderResolver());
                            if (relationFieldNums != null && relationFieldNums.length > 0) {
                                op.provideFields(relationFieldNums, pcFM);
                            }
                        }
                    } catch (NucleusObjectNotFoundException ex) {
                        objectNotFound.add(ids[i]);
                    }
                } else {
                // Was deleted earlier so ignore
                }
            }
            // Remove any of the "reachable" instances that are no longer "reachable"
            flushedNewIds.removeAll(currentReachables);
            Object[] nonReachableIds = flushedNewIds.toArray();
            if (nonReachableIds != null && nonReachableIds.length > 0) {
                // TODO See CORE-3276 for a possible change to this
                for (int i = 0; i < nonReachableIds.length; i++) {
                    if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
                        NucleusLogger.PERSISTENCE.debug(Localiser.msg("010033", nonReachableIds[i]));
                    }
                    try {
                        if (!objectNotFound.contains(nonReachableIds[i])) {
                            ObjectProvider op = ec.findObjectProvider(ec.findObject(nonReachableIds[i], true, true, null));
                            if (!op.getLifecycleState().isDeleted() && !ec.getApiAdapter().isDetached(op.getObject())) {
                                // Null any relationships for relation fields of this object
                                op.replaceFields(op.getClassMetaData().getNonPKMemberPositions(), new NullifyRelationFieldManager(op));
                                ec.flush();
                            }
                        }
                    } catch (NucleusObjectNotFoundException ex) {
                    // just ignore if the object does not exist anymore
                    }
                }
                // B). Remove the objects
                for (int i = 0; i < nonReachableIds.length; i++) {
                    try {
                        if (!objectNotFound.contains(nonReachableIds[i])) {
                            ObjectProvider op = ec.findObjectProvider(ec.findObject(nonReachableIds[i], true, true, null));
                            op.deletePersistent();
                        }
                    } catch (NucleusObjectNotFoundException ex) {
                    // just ignore if the file does not exist anymore
                    }
                }
            }
            // Make sure any updates are flushed
            ec.flushInternal(true);
        }
        if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
            NucleusLogger.PERSISTENCE.debug(Localiser.msg("010034"));
        }
    } finally {
        this.executing = false;
    }
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) NullifyRelationFieldManager(org.datanucleus.store.fieldmanager.NullifyRelationFieldManager) ReachabilityFieldManager(org.datanucleus.store.fieldmanager.ReachabilityFieldManager) ObjectProvider(org.datanucleus.state.ObjectProvider) NucleusObjectNotFoundException(org.datanucleus.exceptions.NucleusObjectNotFoundException) HashSet(java.util.HashSet)

Example 22 with NucleusObjectNotFoundException

use of org.datanucleus.exceptions.NucleusObjectNotFoundException in project datanucleus-core by datanucleus.

the class ExecutionContextImpl method performDetachAllOnTxnEndPreparation.

/**
 * Method to perform all necessary preparation for detach-all-on-commit/detach-all-on-rollback.
 * Identifies all objects affected and makes sure that all fetch plan fields are loaded.
 */
private void performDetachAllOnTxnEndPreparation() {
    // JDO spec 12.7.3 "Root instances"
    // "Root instances are parameter instances for retrieve, detachCopy, and refresh; result
    // instances for queries. Root instances for DetachAllOnCommit are defined explicitly by
    // the user via the FetchPlan property DetachmentRoots or DetachmentRootClasses.
    // If not set explicitly, the detachment roots consist of the union of all root instances of
    // methods executed since the last commit or rollback."
    Collection<ObjectProvider> ops = new ArrayList<>();
    Collection roots = fetchPlan.getDetachmentRoots();
    Class[] rootClasses = fetchPlan.getDetachmentRootClasses();
    if (roots != null && !roots.isEmpty()) {
        // Detachment roots specified
        for (Object root : roots) {
            ops.add(findObjectProvider(root));
        }
    } else if (rootClasses != null && rootClasses.length > 0) {
        // Detachment root classes specified
        ObjectProvider[] txOPs = enlistedOPCache.values().toArray(new ObjectProvider[enlistedOPCache.size()]);
        for (int i = 0; i < txOPs.length; i++) {
            for (int j = 0; j < rootClasses.length; j++) {
                // Check if object is of this root type
                if (txOPs[i].getObject().getClass() == rootClasses[j]) {
                    // This ObjectProvider is for a valid root object
                    ops.add(txOPs[i]);
                    break;
                }
            }
        }
    } else if (cache != null && !cache.isEmpty()) {
        // Detach all objects in the L1 cache
        ops.addAll(cache.values());
    }
    // Make sure that all FetchPlan fields are loaded
    Iterator<ObjectProvider> opsIter = ops.iterator();
    while (opsIter.hasNext()) {
        ObjectProvider op = opsIter.next();
        Object pc = op.getObject();
        if (pc != null && !getApiAdapter().isDetached(pc) && !getApiAdapter().isDeleted(pc)) {
            // Load all fields (and sub-objects) in the FetchPlan
            FetchPlanState state = new FetchPlanState();
            try {
                op.loadFieldsInFetchPlan(state);
            } catch (NucleusObjectNotFoundException onfe) {
                // This object doesnt exist in the datastore at this point.
                // Either the user has some other process that has deleted it or they have
                // defined datastore based cascade delete and it has been deleted that way
                NucleusLogger.PERSISTENCE.warn(Localiser.msg("010013", StringUtils.toJVMIDString(pc), op.getInternalObjectId()));
                opsIter.remove();
            // TODO Move the object state to P_DELETED for consistency
            }
        }
    }
    detachAllOnTxnEndOPs = ops.toArray(new ObjectProvider[ops.size()]);
}
Also used : ArrayList(java.util.ArrayList) Collection(java.util.Collection) ObjectProvider(org.datanucleus.state.ObjectProvider) NucleusObjectNotFoundException(org.datanucleus.exceptions.NucleusObjectNotFoundException)

Example 23 with NucleusObjectNotFoundException

use of org.datanucleus.exceptions.NucleusObjectNotFoundException in project datanucleus-core by datanucleus.

the class ExecutionContextImpl method persistObjectInternal.

/**
 * Method to make an object persistent which should be called from internal calls only.
 * All PM/EM calls should go via persistObject(Object obj).
 * @param obj The object
 * @param preInsertChanges Any changes to make before inserting
 * @param ownerOP ObjectProvider of the owner when embedded
 * @param ownerFieldNum Field number in the owner where this is embedded (or -1 if not embedded)
 * @param objectType Type of object (see org.datanucleus.ObjectProvider, e.g ObjectProvider.PC)
 * @return The persisted object
 * @throws NucleusUserException if the object is managed by a different manager
 */
public <T> T persistObjectInternal(T obj, FieldValues preInsertChanges, ObjectProvider ownerOP, int ownerFieldNum, int objectType) {
    if (obj == null) {
        return null;
    }
    // TODO Support embeddedOwner/objectType, so we can add ObjectProvider for embedded objects here
    ApiAdapter api = getApiAdapter();
    // Id of the object that was persisted during this process (if any)
    Object id = null;
    try {
        clr.setPrimary(obj.getClass().getClassLoader());
        assertClassPersistable(obj.getClass());
        ExecutionContext ec = api.getExecutionContext(obj);
        if (ec != null && ec != this) {
            // Object managed by a different manager
            throw new NucleusUserException(Localiser.msg("010007", obj));
        }
        boolean cacheable = false;
        // Persisted object is the passed in pc (unless being attached as a copy)
        T persistedPc = obj;
        if (api.isDetached(obj)) {
            // Detached : attach it
            assertDetachable(obj);
            if (getBooleanProperty(PropertyNames.PROPERTY_COPY_ON_ATTACH)) {
                // Attach a copy and return the copy
                persistedPc = attachObjectCopy(ownerOP, obj, api.getIdForObject(obj) == null);
            } else {
                // Attach the object
                attachObject(ownerOP, obj, api.getIdForObject(obj) == null);
                persistedPc = obj;
            }
        } else if (api.isTransactional(obj) && !api.isPersistent(obj)) {
            // TransientTransactional : persist it
            if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
                NucleusLogger.PERSISTENCE.debug(Localiser.msg("010015", StringUtils.toJVMIDString(obj)));
            }
            ObjectProvider op = findObjectProvider(obj);
            if (op == null) {
                throw new NucleusUserException(Localiser.msg("010007", getApiAdapter().getIdForObject(obj)));
            }
            op.makePersistentTransactionalTransient();
        } else if (!api.isPersistent(obj)) {
            // Transient : persist it
            if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
                NucleusLogger.PERSISTENCE.debug(Localiser.msg("010015", StringUtils.toJVMIDString(obj)));
            }
            boolean merged = false;
            ThreadContextInfo threadInfo = acquireThreadContextInfo();
            try {
                if (threadInfo.merging) {
                    AbstractClassMetaData cmd = getMetaDataManager().getMetaDataForClass(obj.getClass(), clr);
                    if (cmd.getIdentityType() == IdentityType.APPLICATION) {
                        Object transientId = nucCtx.getIdentityManager().getApplicationId(obj, cmd);
                        if (transientId != null) {
                            // User has set id field(s) so find the datastore object (if exists)
                            T existingObj = (T) findObject(transientId, true, true, cmd.getFullClassName());
                            ObjectProvider existingOP = findObjectProvider(existingObj);
                            existingOP.attach(obj);
                            id = transientId;
                            merged = true;
                            persistedPc = existingObj;
                        }
                    }
                    cacheable = nucCtx.isClassCacheable(cmd);
                }
            } catch (NucleusObjectNotFoundException onfe) {
            // Object with this id doesn't exist, so just persist the transient (below)
            } finally {
                releaseThreadContextInfo();
            }
            if (!merged) {
                ObjectProvider<T> op = findObjectProvider(obj);
                if (op == null) {
                    if ((objectType == ObjectProvider.EMBEDDED_COLLECTION_ELEMENT_PC || objectType == ObjectProvider.EMBEDDED_MAP_KEY_PC || objectType == ObjectProvider.EMBEDDED_MAP_VALUE_PC || objectType == ObjectProvider.EMBEDDED_PC) && ownerOP != null) {
                        // SCO object
                        op = nucCtx.getObjectProviderFactory().newForEmbedded(this, obj, false, ownerOP, ownerFieldNum);
                        op.setPcObjectType((short) objectType);
                        op.makePersistent();
                        id = op.getInternalObjectId();
                    } else {
                        // FCO object
                        op = nucCtx.getObjectProviderFactory().newForPersistentNew(this, obj, preInsertChanges);
                        op.makePersistent();
                        id = op.getInternalObjectId();
                    }
                } else {
                    if (op.getReferencedPC() == null) {
                        // Persist it
                        op.makePersistent();
                        id = op.getInternalObjectId();
                    } else {
                        // Being attached, so use the attached object
                        persistedPc = op.getReferencedPC();
                    }
                }
                if (op != null) {
                    cacheable = nucCtx.isClassCacheable(op.getClassMetaData());
                }
            }
        } else if (api.isPersistent(obj) && api.getIdForObject(obj) == null) {
            // Should we be making a copy of the object here ?
            if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
                NucleusLogger.PERSISTENCE.debug(Localiser.msg("010015", StringUtils.toJVMIDString(obj)));
            }
            ObjectProvider op = findObjectProvider(obj);
            op.makePersistent();
            id = op.getInternalObjectId();
            cacheable = nucCtx.isClassCacheable(op.getClassMetaData());
        } else if (api.isDeleted(obj)) {
            // Deleted : (re)-persist it (permitted in JPA, but not JDO - see ObjectProvider)
            if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
                NucleusLogger.PERSISTENCE.debug(Localiser.msg("010015", StringUtils.toJVMIDString(obj)));
            }
            ObjectProvider op = findObjectProvider(obj);
            op.makePersistent();
            id = op.getInternalObjectId();
            cacheable = nucCtx.isClassCacheable(op.getClassMetaData());
        } else {
            if (api.isPersistent(obj) && api.isTransactional(obj) && api.isDirty(obj) && isDelayDatastoreOperationsEnabled()) {
                // Object provisionally persistent (but not in datastore) so re-run reachability maybe
                if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
                    NucleusLogger.PERSISTENCE.debug(Localiser.msg("010015", StringUtils.toJVMIDString(obj)));
                }
                ObjectProvider op = findObjectProvider(obj);
                op.makePersistent();
                id = op.getInternalObjectId();
                cacheable = nucCtx.isClassCacheable(op.getClassMetaData());
            }
        }
        if (id != null && l2CacheTxIds != null && cacheable) {
            l2CacheTxIds.add(id);
        }
        return persistedPc;
    } finally {
        clr.unsetPrimary();
    }
}
Also used : ApiAdapter(org.datanucleus.api.ApiAdapter) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) ObjectProvider(org.datanucleus.state.ObjectProvider) NucleusObjectNotFoundException(org.datanucleus.exceptions.NucleusObjectNotFoundException) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData)

Example 24 with NucleusObjectNotFoundException

use of org.datanucleus.exceptions.NucleusObjectNotFoundException in project datanucleus-core by datanucleus.

the class ExecutionContextImpl method getClassDetailsForId.

/**
 * Convenience method that takes an id, an optional class name for the object it represents, and whether
 * to check for inheritance, and returns class details of the object being represented.
 * Used by the findObject process.
 * @param id The identity
 * @param objectClassName Class name for the object (if known, otherwise is derived)
 * @param checkInheritance Whether to check the inheritance level for this id
 * @return The details for the class
 */
private ClassDetailsForId getClassDetailsForId(Object id, String objectClassName, boolean checkInheritance) {
    // Object not found yet, so work out class name
    String className = null;
    String originalClassName = null;
    boolean checkedClassName = false;
    if (id instanceof SCOID) {
        throw new NucleusUserException(Localiser.msg("010006"));
    } else if (id instanceof DatastoreUniqueLongId) {
        // Should have been found using "persistenceHandler.findObject()"
        throw new NucleusObjectNotFoundException(Localiser.msg("010026"), id);
    } else if (objectClassName != null) {
        // Object class name specified so use that directly
        originalClassName = objectClassName;
    } else {
        originalClassName = getStoreManager().manageClassForIdentity(id, clr);
    }
    if (originalClassName == null) {
        // We dont know the object class so try to deduce it from what is known by the StoreManager
        originalClassName = getClassNameForObjectId(id);
        checkedClassName = true;
    }
    Object pc = null;
    if (checkInheritance) {
        // Validate the inheritance level
        className = checkedClassName ? originalClassName : getClassNameForObjectId(id);
        if (className == null) {
            throw new NucleusObjectNotFoundException(Localiser.msg("010026"), id);
        }
        if (!checkedClassName) {
            // Check if this id for any known subclasses is in the cache to save searching
            if (IdentityUtils.isDatastoreIdentity(id) || IdentityUtils.isSingleFieldIdentity(id)) {
                String[] subclasses = getMetaDataManager().getSubclassesForClass(className, true);
                if (subclasses != null) {
                    for (int i = 0; i < subclasses.length; i++) {
                        Object oid = null;
                        if (IdentityUtils.isDatastoreIdentity(id)) {
                            oid = nucCtx.getIdentityManager().getDatastoreId(subclasses[i], IdentityUtils.getTargetKeyForDatastoreIdentity(id));
                        } else if (IdentityUtils.isSingleFieldIdentity(id)) {
                            oid = nucCtx.getIdentityManager().getSingleFieldId(id.getClass(), getClassLoaderResolver().classForName(subclasses[i]), IdentityUtils.getTargetKeyForSingleFieldIdentity(id));
                        }
                        pc = getObjectFromCache(oid);
                        if (pc != null) {
                            className = subclasses[i];
                            break;
                        }
                    }
                }
            }
        }
        if (pc == null && originalClassName != null && !originalClassName.equals(className)) {
            // Inheritance check implies different inheritance level, so retry
            if (IdentityUtils.isDatastoreIdentity(id)) {
                // Create new OID using correct target class, and recheck cache
                id = nucCtx.getIdentityManager().getDatastoreId(className, ((DatastoreId) id).getKeyAsObject());
                pc = getObjectFromCache(id);
            } else if (IdentityUtils.isSingleFieldIdentity(id)) {
                // Create new SingleFieldIdentity using correct targetClass, and recheck cache
                id = nucCtx.getIdentityManager().getSingleFieldId(id.getClass(), clr.classForName(className), IdentityUtils.getTargetKeyForSingleFieldIdentity(id));
                pc = getObjectFromCache(id);
            }
        }
    } else {
        className = originalClassName;
    }
    return new ClassDetailsForId(id, className, pc);
}
Also used : DatastoreId(org.datanucleus.identity.DatastoreId) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) SCOID(org.datanucleus.identity.SCOID) DatastoreUniqueLongId(org.datanucleus.identity.DatastoreUniqueLongId) NucleusObjectNotFoundException(org.datanucleus.exceptions.NucleusObjectNotFoundException)

Example 25 with NucleusObjectNotFoundException

use of org.datanucleus.exceptions.NucleusObjectNotFoundException in project datanucleus-rdbms by datanucleus.

the class FetchRequest method execute.

/* (non-Javadoc)
     * @see org.datanucleus.store.rdbms.request.Request#execute(org.datanucleus.state.DNStateManager)
     */
public void execute(DNStateManager sm) {
    if (fieldsToFetch != null && NucleusLogger.PERSISTENCE.isDebugEnabled()) {
        // Debug information about what we are retrieving
        NucleusLogger.PERSISTENCE.debug(Localiser.msg("052218", IdentityUtils.getPersistableIdentityForId(sm.getInternalObjectId()), fieldsToFetch, table));
    }
    if (((fetchingSurrogateVersion || versionFieldName != null) && numberOfFieldsToFetch == 0) && sm.isVersionLoaded()) {
    // Fetching only the version and it is already loaded, so do nothing
    } else if (statementLocked != null) {
        ExecutionContext ec = sm.getExecutionContext();
        RDBMSStoreManager storeMgr = table.getStoreManager();
        // Override with pessimistic lock where specified
        LockMode lockType = ec.getLockManager().getLockMode(sm.getInternalObjectId());
        boolean locked = (lockType == LockMode.LOCK_PESSIMISTIC_READ || lockType == LockMode.LOCK_PESSIMISTIC_WRITE) ? true : ec.getSerializeReadForClass(sm.getClassMetaData().getFullClassName());
        String statement = (locked ? statementLocked : statementUnlocked);
        StatementClassMapping mappingDef = mappingDefinition;
        /*if ((sm.isDeleting() || sm.isDetaching()) && mappingDefinition.hasChildMappingDefinitions())
            {
                // Don't fetch any children since the object is being deleted
                mappingDef = mappingDefinition.cloneStatementMappingWithoutChildren();
            }*/
        try {
            ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
            SQLController sqlControl = storeMgr.getSQLController();
            try {
                PreparedStatement ps = sqlControl.getStatementForQuery(mconn, statement);
                AbstractClassMetaData cmd = sm.getClassMetaData();
                try {
                    // Provide the primary key field(s) to the JDBC statement
                    if (cmd.getIdentityType() == IdentityType.DATASTORE) {
                        StatementMappingIndex datastoreIdx = mappingDef.getMappingForMemberPosition(SurrogateColumnType.DATASTORE_ID.getFieldNumber());
                        for (int i = 0; i < datastoreIdx.getNumberOfParameterOccurrences(); i++) {
                            table.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false).setObject(ec, ps, datastoreIdx.getParameterPositionsForOccurrence(i), sm.getInternalObjectId());
                        }
                    } else if (cmd.getIdentityType() == IdentityType.APPLICATION) {
                        sm.provideFields(cmd.getPKMemberPositions(), new ParameterSetter(sm, ps, mappingDef));
                    }
                    JavaTypeMapping multitenancyMapping = table.getSurrogateMapping(SurrogateColumnType.MULTITENANCY, false);
                    if (multitenancyMapping != null) {
                        String[] tenantReadIds = storeMgr.getNucleusContext().getTenantReadIds(sm.getExecutionContext());
                        if (tenantReadIds != null && tenantReadIds.length > 0) {
                        // Using IN clause so nothing to do since hardcoded
                        } else {
                            // Set MultiTenancy tenant id in statement
                            StatementMappingIndex multitenancyIdx = mappingDef.getMappingForMemberPosition(SurrogateColumnType.MULTITENANCY.getFieldNumber());
                            String tenantId = ec.getTenantId();
                            for (int i = 0; i < multitenancyIdx.getNumberOfParameterOccurrences(); i++) {
                                multitenancyMapping.setObject(ec, ps, multitenancyIdx.getParameterPositionsForOccurrence(i), tenantId);
                            }
                        }
                    }
                    JavaTypeMapping softDeleteMapping = table.getSurrogateMapping(SurrogateColumnType.SOFTDELETE, false);
                    if (softDeleteMapping != null) {
                        // Set SoftDelete parameter in statement
                        StatementMappingIndex softDeleteIdx = mappingDefinition.getMappingForMemberPosition(SurrogateColumnType.SOFTDELETE.getFieldNumber());
                        for (int i = 0; i < softDeleteIdx.getNumberOfParameterOccurrences(); i++) {
                            softDeleteMapping.setObject(ec, ps, softDeleteIdx.getParameterPositionsForOccurrence(i), Boolean.FALSE);
                        }
                    }
                    // Execute the statement
                    ResultSet rs = sqlControl.executeStatementQuery(ec, mconn, statement, ps);
                    try {
                        // Check for failure to find the object
                        if (!rs.next()) {
                            String msg = Localiser.msg("050018", IdentityUtils.getPersistableIdentityForId(sm.getInternalObjectId()));
                            if (NucleusLogger.DATASTORE_RETRIEVE.isInfoEnabled()) {
                                NucleusLogger.DATASTORE_RETRIEVE.info(msg);
                            }
                            throw new NucleusObjectNotFoundException(msg);
                        }
                        // Copy the results into the object
                        ResultSetGetter rsGetter = new ResultSetGetter(ec, rs, mappingDef, sm.getClassMetaData());
                        rsGetter.setStateManager(sm);
                        // Make sure the version is set first
                        if (sm.getTransactionalVersion() == null) {
                            // Object has no version set so update it from this fetch
                            Object datastoreVersion = null;
                            if (fetchingSurrogateVersion) {
                                // Surrogate version column - get from the result set using the version mapping
                                StatementMappingIndex verIdx = mappingDef.getMappingForMemberPosition(SurrogateColumnType.VERSION.getFieldNumber());
                                datastoreVersion = table.getSurrogateMapping(SurrogateColumnType.VERSION, true).getObject(ec, rs, verIdx.getColumnPositions());
                            } else if (versionFieldName != null) {
                                // Version field - populate it in the object and access it from the field
                                int verAbsFieldNum = cmd.getAbsolutePositionOfMember(versionFieldName);
                                sm.replaceFields(new int[] { verAbsFieldNum }, rsGetter);
                                datastoreVersion = sm.provideField(verAbsFieldNum);
                            }
                            sm.setVersion(datastoreVersion);
                        }
                        // Fetch requested fields
                        sm.replaceFields(memberNumbersToFetch, rsGetter);
                        // Store requested fields
                        if (memberNumbersToStore != null) {
                            for (int i = 0; i < memberNumbersToStore.length; i++) {
                                StatementMappingIndex mapIdx = mappingDefinition.getMappingForMemberPosition(memberNumbersToStore[i]);
                                JavaTypeMapping m = mapIdx.getMapping();
                                if (m instanceof PersistableMapping) {
                                    // FK, so create the identity of the related object
                                    AbstractClassMetaData memberCmd = ((PersistableMapping) m).getClassMetaData();
                                    Object memberId = null;
                                    if (memberCmd.getIdentityType() == IdentityType.DATASTORE) {
                                        memberId = MappingHelper.getDatastoreIdentityForResultSetRow(ec, m, rs, mapIdx.getColumnPositions(), memberCmd);
                                    } else if (memberCmd.getIdentityType() == IdentityType.APPLICATION) {
                                        memberId = MappingHelper.getApplicationIdentityForResultSetRow(ec, m, rs, mapIdx.getColumnPositions(), memberCmd);
                                    } else {
                                        break;
                                    }
                                    if (memberId == null) {
                                        // Just set the member and don't bother saving the value
                                        sm.replaceField(memberNumbersToStore[i], null);
                                    } else {
                                        // Store the "id" value in case the member is ever accessed
                                        sm.storeFieldValue(memberNumbersToStore[i], memberId);
                                    }
                                }
                            }
                        }
                    } finally {
                        rs.close();
                    }
                } finally {
                    sqlControl.closeStatement(mconn, ps);
                }
            } finally {
                mconn.release();
            }
        } catch (SQLException sqle) {
            String msg = Localiser.msg("052219", IdentityUtils.getPersistableIdentityForId(sm.getInternalObjectId()), statement, sqle.getMessage());
            NucleusLogger.DATASTORE_RETRIEVE.warn(msg);
            List exceptions = new ArrayList();
            exceptions.add(sqle);
            while ((sqle = sqle.getNextException()) != null) {
                exceptions.add(sqle);
            }
            throw new NucleusDataStoreException(msg, (Throwable[]) exceptions.toArray(new Throwable[exceptions.size()]));
        }
    }
    // Execute any mapping actions now that we have fetched the fields
    if (mappingCallbacks != null) {
        for (MappingCallbacks m : mappingCallbacks) {
            m.postFetch(sm);
        }
    }
}
Also used : JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) SQLException(java.sql.SQLException) MappingCallbacks(org.datanucleus.store.rdbms.mapping.MappingCallbacks) ArrayList(java.util.ArrayList) PreparedStatement(java.sql.PreparedStatement) LockMode(org.datanucleus.state.LockMode) StatementMappingIndex(org.datanucleus.store.rdbms.query.StatementMappingIndex) ParameterSetter(org.datanucleus.store.rdbms.fieldmanager.ParameterSetter) NucleusObjectNotFoundException(org.datanucleus.exceptions.NucleusObjectNotFoundException) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) StatementClassMapping(org.datanucleus.store.rdbms.query.StatementClassMapping) SQLController(org.datanucleus.store.rdbms.SQLController) ResultSetGetter(org.datanucleus.store.rdbms.fieldmanager.ResultSetGetter) NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) PersistableMapping(org.datanucleus.store.rdbms.mapping.java.PersistableMapping) ExecutionContext(org.datanucleus.ExecutionContext) ResultSet(java.sql.ResultSet) ManagedConnection(org.datanucleus.store.connection.ManagedConnection) ArrayList(java.util.ArrayList) List(java.util.List)

Aggregations

NucleusObjectNotFoundException (org.datanucleus.exceptions.NucleusObjectNotFoundException)27 ExecutionContext (org.datanucleus.ExecutionContext)15 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)14 ObjectProvider (org.datanucleus.state.ObjectProvider)12 PreparedStatement (java.sql.PreparedStatement)10 ResultSet (java.sql.ResultSet)10 SQLException (java.sql.SQLException)10 NucleusDataStoreException (org.datanucleus.exceptions.NucleusDataStoreException)10 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)10 ManagedConnection (org.datanucleus.store.connection.ManagedConnection)10 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)10 SQLController (org.datanucleus.store.rdbms.SQLController)10 ParameterSetter (org.datanucleus.store.rdbms.fieldmanager.ParameterSetter)10 StatementMappingIndex (org.datanucleus.store.rdbms.query.StatementMappingIndex)10 ArrayList (java.util.ArrayList)9 List (java.util.List)8 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)8 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)6 ApiAdapter (org.datanucleus.api.ApiAdapter)6 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)6