Search in sources :

Example 16 with NucleusObjectNotFoundException

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

the class StateManagerImpl method checkInheritance.

/**
 * Look to the database to determine which class this object is. This parameter is a hint. Set false, if it's
 * already determined the correct pcClass for this pc "object" in a certain
 * level in the hierarchy. Set to true and it will look to the database.
 * TODO This is only called by some outdated code in LDAPUtils; remove it when that is fixed
 * @param fv the initial field values of the object.
 * @deprecated Dont use this, to be removed
 */
public void checkInheritance(FieldValues fv) {
    // Inheritance case, check the level of the instance
    ClassLoaderResolver clr = myEC.getClassLoaderResolver();
    String className = getStoreManager().getClassNameForObjectID(myID, clr, myEC);
    if (className == null) {
        // className is null when id class exists, and object has been validated and doesn't exist.
        throw new NucleusObjectNotFoundException(Localiser.msg("026013", IdentityUtils.getPersistableIdentityForId(myID)), myID);
    } else if (!cmd.getFullClassName().equals(className)) {
        Class pcClass;
        try {
            // load the class and make sure the class is initialized
            pcClass = clr.classForName(className, myID.getClass().getClassLoader(), true);
            cmd = myEC.getMetaDataManager().getMetaDataForClass(pcClass, clr);
        } catch (ClassNotResolvedException e) {
            NucleusLogger.PERSISTENCE.warn(Localiser.msg("026014", IdentityUtils.getPersistableIdentityForId(myID)));
            throw new NucleusUserException(Localiser.msg("026014", IdentityUtils.getPersistableIdentityForId(myID)), e);
        }
        if (cmd == null) {
            throw new NucleusUserException(Localiser.msg("026012", pcClass)).setFatal();
        }
        if (cmd.getIdentityType() != IdentityType.APPLICATION) {
            throw new NucleusUserException("This method should only be used for objects using application identity.").setFatal();
        }
        myFP = myEC.getFetchPlan().getFetchPlanForClass(cmd);
        int fieldCount = cmd.getMemberCount();
        dirtyFields = new boolean[fieldCount];
        loadedFields = new boolean[fieldCount];
        // Create new PC at right inheritance level
        myPC = HELPER.newInstance(pcClass, this);
        if (myPC == null) {
            throw new NucleusUserException(Localiser.msg("026018", cmd.getFullClassName())).setFatal();
        }
        // Note that this will mean the fields are loaded twice (loaded earlier in this method)
        // and also that postLoad will be called twice
        loadFieldValues(fv);
        // Create the id for the new PC
        myID = myEC.getNucleusContext().getIdentityManager().getApplicationId(myPC, cmd);
    }
}
Also used : NucleusUserException(org.datanucleus.exceptions.NucleusUserException) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) FetchPlanForClass(org.datanucleus.FetchPlanForClass) NucleusObjectNotFoundException(org.datanucleus.exceptions.NucleusObjectNotFoundException) ClassNotResolvedException(org.datanucleus.exceptions.ClassNotResolvedException)

Example 17 with NucleusObjectNotFoundException

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

the class PersistableMapping method preDelete.

/**
 * Method executed just before the owning object is deleted, allowing tidying up of any relation information.
 * @param op ObjectProvider for the owner
 */
public void preDelete(ObjectProvider op) {
    int fieldNumber = mmd.getAbsoluteFieldNumber();
    if (!op.isFieldLoaded(fieldNumber)) {
        // makes sure field is loaded
        try {
            op.loadField(fieldNumber);
        } catch (NucleusObjectNotFoundException onfe) {
            // Already deleted so just return
            return;
        }
    }
    Object pc = op.provideField(fieldNumber);
    pc = mmd.isSingleCollection() ? SCOUtils.singleCollectionValue(getStoreManager().getNucleusContext().getTypeManager(), pc) : pc;
    if (pc == null) {
        // Null value so nothing to do
        return;
    }
    ExecutionContext ec = op.getExecutionContext();
    ClassLoaderResolver clr = ec.getClassLoaderResolver();
    // N-1 Uni, so delete join table entry
    RelationType relationType = mmd.getRelationType(clr);
    if (relationType == RelationType.MANY_TO_ONE_UNI) {
        // Update join table entry
        PersistableRelationStore store = (PersistableRelationStore) storeMgr.getBackingStoreForField(clr, mmd, mmd.getType());
        store.remove(op);
    }
    // Check if we should delete the related object when this object is deleted
    boolean dependent = mmd.isDependent();
    if (mmd.isCascadeRemoveOrphans()) {
        // JPA allows "orphan removal" to define deletion of the other side
        dependent = true;
    }
    // Check if the field has a FK defined
    AbstractMemberMetaData[] relatedMmds = mmd.getRelatedMemberMetaData(clr);
    // TODO Cater for more than 1 related field
    boolean hasFK = false;
    if (!dependent) {
        // Not dependent, so check if the datastore has a FK and will take care of it for us
        if (mmd.getForeignKeyMetaData() != null) {
            hasFK = true;
        }
        if (RelationType.isBidirectional(relationType) && relatedMmds[0].getForeignKeyMetaData() != null) {
            hasFK = true;
        }
        if (ec.getStringProperty(PropertyNames.PROPERTY_DELETION_POLICY).equals("JDO2")) {
            // JDO doesn't currently take note of foreign-key
            hasFK = false;
        }
    }
    // There may be some corner cases that this code doesn't yet cater for
    if (relationType == RelationType.ONE_TO_ONE_UNI || (relationType == RelationType.ONE_TO_ONE_BI && mmd.getMappedBy() == null)) {
        // 1-1 with FK at this side (owner of the relation)
        if (dependent) {
            boolean relatedObjectDeleted = ec.getApiAdapter().isDeleted(pc);
            if (isNullable() && !relatedObjectDeleted) {
                // Other object not yet deleted, but the field is nullable so just null out the FK
                // TODO Not doing this would cause errors in 1-1 uni relations (e.g AttachDetachTest)
                // TODO Log this since it affects the resultant objects
                op.replaceFieldMakeDirty(fieldNumber, null);
                storeMgr.getPersistenceHandler().updateObject(op, new int[] { fieldNumber });
                if (!relatedObjectDeleted) {
                    // Mark the other object for deletion since not yet tagged
                    ec.deleteObjectInternal(pc);
                }
            } else {
                // Can't just delete the other object since that would cause a FK constraint violation. Do nothing - handled by DeleteRequest on other object
                if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
                    NucleusLogger.DATASTORE_PERSIST.debug(Localiser.msg("041017", StringUtils.toJVMIDString(op.getObject()), mmd.getFullFieldName()));
                }
            }
        } else {
            // We're deleting the FK at this side so shouldn't be an issue
            AbstractMemberMetaData relatedMmd = mmd.getRelatedMemberMetaDataForObject(clr, op.getObject(), pc);
            if (relatedMmd != null) {
                ObjectProvider otherOP = ec.findObjectProvider(pc);
                if (otherOP != null) {
                    // Managed Relations : 1-1 bidir, so null out the object at the other
                    Object currentValue = otherOP.provideField(relatedMmd.getAbsoluteFieldNumber());
                    if (currentValue != null) {
                        if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
                            NucleusLogger.PERSISTENCE.debug(Localiser.msg("041019", StringUtils.toJVMIDString(pc), relatedMmd.getFullFieldName(), op.getObjectAsPrintable()));
                        }
                        otherOP.replaceFieldMakeDirty(relatedMmd.getAbsoluteFieldNumber(), null);
                        if (ec.getManageRelations()) {
                            otherOP.getExecutionContext().getRelationshipManager(otherOP).relationChange(relatedMmd.getAbsoluteFieldNumber(), op.getObject(), null);
                        }
                    }
                }
            }
        }
    } else if (relationType == RelationType.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 otherOP = ec.findObjectProvider(pc);
        if (dependent) {
            if (isNullable) {
                // Null out the FK in the datastore using a direct update (since we are deleting)
                otherOP.replaceFieldMakeDirty(relatedMmds[0].getAbsoluteFieldNumber(), null);
                storeMgr.getPersistenceHandler().updateObject(otherOP, new int[] { relatedMmds[0].getAbsoluteFieldNumber() });
            }
            // Mark the other object for deletion
            ec.deleteObjectInternal(pc);
        } else if (!hasFK) {
            if (isNullable()) {
                Object currentRelatedValue = otherOP.provideField(relatedMmds[0].getAbsoluteFieldNumber());
                if (currentRelatedValue != null) {
                    // Null out the FK in the datastore using a direct update (since we are deleting)
                    otherOP.replaceFieldMakeDirty(relatedMmds[0].getAbsoluteFieldNumber(), null);
                    storeMgr.getPersistenceHandler().updateObject(otherOP, new int[] { relatedMmds[0].getAbsoluteFieldNumber() });
                    // Managed Relations : 1-1 bidir, so null out the object at the other
                    if (ec.getManageRelations()) {
                        otherOP.getExecutionContext().getRelationshipManager(otherOP).relationChange(relatedMmds[0].getAbsoluteFieldNumber(), op.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 == RelationType.MANY_TO_ONE_BI) {
        ObjectProvider otherOP = ec.findObjectProvider(pc);
        if (relatedMmds[0].getJoinMetaData() == null) {
            // N-1 with FK at this side
            if (otherOP.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)
                        op.replaceFieldMakeDirty(fieldNumber, null);
                        storeMgr.getPersistenceHandler().updateObject(op, 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(otherOP.getObject()) && !otherOP.isDeleting()) {
                            // Make sure the other object is updated in any caches
                            ec.markDirty(otherOP, false);
                            // Make sure collection field is loaded
                            otherOP.isLoaded(relatedMmds[0].getAbsoluteFieldNumber());
                            Collection otherColl = (Collection) otherOP.provideField(relatedMmds[0].getAbsoluteFieldNumber());
                            if (otherColl != null) {
                                if (ec.getManageRelations()) {
                                    otherOP.getExecutionContext().getRelationshipManager(otherOP).relationRemove(relatedMmds[0].getAbsoluteFieldNumber(), op.getObject());
                                }
                                // TODO Localise this message
                                NucleusLogger.PERSISTENCE.debug("ManagedRelationships : delete of object causes removal from collection at " + relatedMmds[0].getFullFieldName());
                                otherColl.remove(op.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(otherOP.getObject()) && !otherOP.isDeleting()) {
                        // Make sure the other object is updated in any caches
                        ec.markDirty(otherOP, false);
                        // Make sure the other object has the collection loaded so does this change
                        otherOP.isLoaded(relatedMmds[0].getAbsoluteFieldNumber());
                        Collection otherColl = (Collection) otherOP.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(op.getObject());
                        }
                    }
                } else if (relatedMmds[0].hasMap()) {
                // TODO Cater for maps, but what is the key/value pair ?
                }
            }
        }
    } else if (relationType == RelationType.MANY_TO_ONE_UNI) {
        // N-1 uni with join table
        if (dependent) {
            // Mark the other object for deletion
            ec.deleteObjectInternal(pc);
        }
    } else {
    // No relation so what is this field ?
    }
}
Also used : ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) NucleusObjectNotFoundException(org.datanucleus.exceptions.NucleusObjectNotFoundException) ExecutionContext(org.datanucleus.ExecutionContext) RelationType(org.datanucleus.metadata.RelationType) Collection(java.util.Collection) SCOCollection(org.datanucleus.store.types.SCOCollection) ObjectProvider(org.datanucleus.state.ObjectProvider) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) PersistableRelationStore(org.datanucleus.store.types.scostore.PersistableRelationStore)

Example 18 with NucleusObjectNotFoundException

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

the class OracleBlobRDBMSMapping method updateBlobColumn.

/**
 * Convenience method to update the contents of a BLOB column.
 * Oracle requires that a BLOB is initialised with EMPTY_BLOB() and then you retrieve
 * the column and update its BLOB value. Performs a statement
 * <pre>
 * SELECT {blobColumn} FROM TABLE WHERE ID=? FOR UPDATE
 * </pre>
 * and then updates the Blob value returned.
 * @param op ObjectProvider of the object
 * @param table Table storing the BLOB column
 * @param mapping Datastore mapping for the BLOB column
 * @param bytes The bytes to store in the BLOB
 * @throws NucleusObjectNotFoundException thrown if an object isnt found
 * @throws NucleusDataStoreException thrown if an error occurs in datastore communication
 */
@SuppressWarnings("deprecation")
public static void updateBlobColumn(ObjectProvider op, Table table, DatastoreMapping mapping, byte[] bytes) {
    ExecutionContext ec = op.getExecutionContext();
    RDBMSStoreManager storeMgr = table.getStoreManager();
    // Don't support join tables yet
    DatastoreClass classTable = (DatastoreClass) table;
    SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
    // Generate "SELECT {blobColumn} FROM TABLE WHERE ID=? FOR UPDATE" statement
    SelectStatement sqlStmt = new SelectStatement(storeMgr, table, null, null);
    sqlStmt.setClassLoaderResolver(ec.getClassLoaderResolver());
    sqlStmt.addExtension(SQLStatement.EXTENSION_LOCK_FOR_UPDATE, true);
    SQLTable blobSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(sqlStmt, sqlStmt.getPrimaryTable(), mapping.getJavaTypeMapping());
    sqlStmt.select(blobSqlTbl, mapping.getColumn(), null);
    StatementClassMapping mappingDefinition = new StatementClassMapping();
    AbstractClassMetaData cmd = op.getClassMetaData();
    int inputParamNum = 1;
    if (cmd.getIdentityType() == IdentityType.DATASTORE) {
        // Datastore identity value for input
        JavaTypeMapping datastoreIdMapping = classTable.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false);
        SQLExpression expr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), datastoreIdMapping);
        SQLExpression val = exprFactory.newLiteralParameter(sqlStmt, datastoreIdMapping, null, "ID");
        sqlStmt.whereAnd(expr.eq(val), true);
        StatementMappingIndex datastoreIdx = mappingDefinition.getMappingForMemberPosition(SurrogateColumnType.DATASTORE_ID.getFieldNumber());
        if (datastoreIdx == null) {
            datastoreIdx = new StatementMappingIndex(datastoreIdMapping);
            mappingDefinition.addMappingForMember(SurrogateColumnType.DATASTORE_ID.getFieldNumber(), datastoreIdx);
        }
        datastoreIdx.addParameterOccurrence(new int[] { inputParamNum });
    } else if (cmd.getIdentityType() == IdentityType.APPLICATION) {
        // Application identity value(s) for input
        int[] pkNums = cmd.getPKMemberPositions();
        for (int i = 0; i < pkNums.length; i++) {
            AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkNums[i]);
            JavaTypeMapping pkMapping = classTable.getMemberMapping(mmd);
            SQLExpression expr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), pkMapping);
            SQLExpression val = exprFactory.newLiteralParameter(sqlStmt, pkMapping, null, "PK" + i);
            sqlStmt.whereAnd(expr.eq(val), true);
            StatementMappingIndex pkIdx = mappingDefinition.getMappingForMemberPosition(pkNums[i]);
            if (pkIdx == null) {
                pkIdx = new StatementMappingIndex(pkMapping);
                mappingDefinition.addMappingForMember(pkNums[i], pkIdx);
            }
            int[] inputParams = new int[pkMapping.getNumberOfDatastoreMappings()];
            for (int j = 0; j < pkMapping.getNumberOfDatastoreMappings(); j++) {
                inputParams[j] = inputParamNum++;
            }
            pkIdx.addParameterOccurrence(inputParams);
        }
    }
    String textStmt = sqlStmt.getSQLText().toSQL();
    if (op.isEmbedded()) {
        // This mapping is embedded, so navigate back to the real owner since that is the "id" in the table
        ObjectProvider[] embeddedOwners = ec.getOwnersForEmbeddedObjectProvider(op);
        if (embeddedOwners != null) {
            // Just use the first owner
            // TODO Should check if the owner is stored in this table
            op = embeddedOwners[0];
        }
    }
    try {
        ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
        SQLController sqlControl = storeMgr.getSQLController();
        try {
            PreparedStatement ps = sqlControl.getStatementForQuery(mconn, textStmt);
            try {
                // Provide the primary key field(s) to the JDBC statement
                if (cmd.getIdentityType() == IdentityType.DATASTORE) {
                    StatementMappingIndex datastoreIdx = mappingDefinition.getMappingForMemberPosition(SurrogateColumnType.DATASTORE_ID.getFieldNumber());
                    for (int i = 0; i < datastoreIdx.getNumberOfParameterOccurrences(); i++) {
                        classTable.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false).setObject(ec, ps, datastoreIdx.getParameterPositionsForOccurrence(i), op.getInternalObjectId());
                    }
                } else if (cmd.getIdentityType() == IdentityType.APPLICATION) {
                    op.provideFields(cmd.getPKMemberPositions(), new ParameterSetter(op, ps, mappingDefinition));
                }
                ResultSet rs = sqlControl.executeStatementQuery(ec, mconn, textStmt, ps);
                try {
                    if (!rs.next()) {
                        throw new NucleusObjectNotFoundException("No such database row", op.getInternalObjectId());
                    }
                    DatastoreAdapter dba = storeMgr.getDatastoreAdapter();
                    int jdbcMajorVersion = dba.getDriverMajorVersion();
                    if (dba.getDatastoreDriverName().equalsIgnoreCase(OracleAdapter.OJDBC_DRIVER_NAME) && jdbcMajorVersion < 10) {
                        // Oracle JDBC drivers version 9 and below use some sh*tty Oracle-specific BLOB type
                        // we have to cast to that, face west, pray whilst saying ommmmmmmmmmm
                        oracle.sql.BLOB blob = null;
                        if (jdbcMajorVersion <= 8) {
                            OracleResultSet ors = (OracleResultSet) rs;
                            blob = ors.getBLOB(1);
                        } else {
                            blob = (oracle.sql.BLOB) rs.getBlob(1);
                        }
                        if (blob != null) {
                            // Deprecated but what can you do
                            blob.putBytes(1, bytes);
                        }
                    } else {
                        // Oracle JDBC drivers 10 and above supposedly use the JDBC standard class for Blobs
                        java.sql.Blob blob = rs.getBlob(1);
                        if (blob != null) {
                            blob.setBytes(1, bytes);
                        }
                    }
                } finally {
                    rs.close();
                }
            } finally {
                sqlControl.closeStatement(mconn, ps);
            }
        } finally {
            mconn.release();
        }
    } catch (SQLException e) {
        throw new NucleusDataStoreException("Update of BLOB value failed: " + textStmt, e);
    }
}
Also used : SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) OracleResultSet(oracle.jdbc.driver.OracleResultSet) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) SQLException(java.sql.SQLException) StatementMappingIndex(org.datanucleus.store.rdbms.query.StatementMappingIndex) ParameterSetter(org.datanucleus.store.rdbms.fieldmanager.ParameterSetter) NucleusObjectNotFoundException(org.datanucleus.exceptions.NucleusObjectNotFoundException) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) SQLController(org.datanucleus.store.rdbms.SQLController) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) ResultSet(java.sql.ResultSet) OracleResultSet(oracle.jdbc.driver.OracleResultSet) ManagedConnection(org.datanucleus.store.connection.ManagedConnection) PreparedStatement(java.sql.PreparedStatement) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) StatementClassMapping(org.datanucleus.store.rdbms.query.StatementClassMapping) ExecutionContext(org.datanucleus.ExecutionContext) ObjectProvider(org.datanucleus.state.ObjectProvider) DatastoreAdapter(org.datanucleus.store.rdbms.adapter.DatastoreAdapter) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) Blob(java.sql.Blob) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 19 with NucleusObjectNotFoundException

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

the class StateManagerImpl method attach.

/**
 * Method to attach the object managed by this StateManager.
 * @param embedded Whether it is embedded
 */
public void attach(boolean embedded) {
    if (isAttaching()) {
        return;
    }
    setAttaching(true);
    try {
        // Check if the object is already persisted
        boolean persistent = false;
        if (embedded) {
            persistent = true;
        } else {
            if (!myEC.getBooleanProperty(PropertyNames.PROPERTY_ATTACH_SAME_DATASTORE)) {
                // We cant assume that this object was detached from this datastore so we check it
                try {
                    locate();
                    persistent = true;
                } catch (NucleusObjectNotFoundException onfe) {
                // Not currently present!
                }
            } else {
                // Assumed detached from this datastore
                persistent = true;
            }
        }
        // Call any "pre-attach" listeners
        getCallbackHandler().preAttach(myPC);
        // Retrieve the updated values from the detached object
        replaceStateManager(myPC, this);
        retrieveDetachState(this);
        if (!persistent) {
            // Persist the object into this datastore first
            makePersistent();
        }
        // Migrate the lifecycle state to persistent
        myLC = myLC.transitionAttach(this);
        // Make sure the attached object goes in the cache
        // [would not get cached when not changed if we didnt do this here]
        myEC.putObjectIntoLevel1Cache(this);
        int[] attachFieldNumbers = getFieldNumbersOfLoadedOrDirtyFields(loadedFields, dirtyFields);
        if (attachFieldNumbers != null) {
            // Only update the fields that were detached, and only update them if there are any to update
            NucleusLogger.GENERAL.debug("Attaching id=" + getInternalObjectId() + " fields=" + StringUtils.intArrayToString(attachFieldNumbers));
            provideFields(attachFieldNumbers, new AttachFieldManager(this, cmd.getSCOMutableMemberFlags(), dirtyFields, persistent, true, false));
        }
        // Call any "post-attach" listeners
        getCallbackHandler().postAttach(myPC, myPC);
    } finally {
        setAttaching(false);
    }
}
Also used : AttachFieldManager(org.datanucleus.store.fieldmanager.AttachFieldManager) NucleusObjectNotFoundException(org.datanucleus.exceptions.NucleusObjectNotFoundException)

Example 20 with NucleusObjectNotFoundException

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

the class AbstractPersistenceHandler method findObjectForUnique.

/* (non-Javadoc)
     * @see org.datanucleus.store.StorePersistenceHandler#findObjectForUnique(org.datanucleus.ExecutionContext, org.datanucleus.metadata.AbstractClassMetaData, java.lang.String[], java.lang.Object[])
     */
@Override
public Object findObjectForUnique(ExecutionContext ec, AbstractClassMetaData cmd, String[] memberNames, Object[] values) {
    if (memberNames.length != values.length) {
        throw new NucleusUserException("findObjectForUnique should have same number of member names and values");
    }
    // Fallback to using a simple JDOQL query (which is what would be performed for the majority of datastores anyway)
    StringBuilder jdoqlStr = new StringBuilder("SELECT FROM ").append(cmd.getFullClassName()).append(" WHERE ");
    Map<String, Object> paramValueMap = new HashMap<>();
    for (int i = 0; i < memberNames.length; i++) {
        jdoqlStr.append("this.").append(memberNames[i]).append(" == :val").append(i);
        paramValueMap.put("val" + i, values[i]);
        if (i != memberNames.length - 1) {
            jdoqlStr.append(" && ");
        }
    }
    Query q = storeMgr.newQuery(Query.LANGUAGE_JDOQL, ec, jdoqlStr.toString());
    List results = (List) q.executeWithMap(paramValueMap);
    if (results == null || results.size() == 0) {
        throw new NucleusObjectNotFoundException("No object found for specified members and values of type " + cmd.getFullClassName());
    } else if (results.size() == 1) {
        return results.get(0);
    }
    throw new NucleusUserException("Specified members for class " + cmd.getFullClassName() + " finds multiple objects!");
}
Also used : Query(org.datanucleus.store.query.Query) HashMap(java.util.HashMap) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) List(java.util.List) NucleusObjectNotFoundException(org.datanucleus.exceptions.NucleusObjectNotFoundException)

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