Search in sources :

Example 16 with NucleusDataStoreException

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

the class LocateBulkRequest method execute.

/**
 * Method performing the location of the records in the datastore.
 * @param ops ObjectProviders to be located
 * @throws NucleusObjectNotFoundException with nested exceptions for each of missing objects (if any)
 */
public void execute(ObjectProvider[] ops) {
    if (ops == null || ops.length == 0) {
        return;
    }
    if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
        // Debug information about what we are retrieving
        StringBuilder str = new StringBuilder();
        for (int i = 0; i < ops.length; i++) {
            if (i > 0) {
                str.append(", ");
            }
            str.append(ops[i].getInternalObjectId());
        }
        NucleusLogger.PERSISTENCE.debug(Localiser.msg("052223", str.toString(), table));
    }
    ExecutionContext ec = ops[0].getExecutionContext();
    RDBMSStoreManager storeMgr = table.getStoreManager();
    AbstractClassMetaData cmd = ops[0].getClassMetaData();
    boolean locked = ec.getSerializeReadForClass(cmd.getFullClassName());
    LockMode lockType = ec.getLockManager().getLockMode(ops[0].getInternalObjectId());
    if (lockType != LockMode.LOCK_NONE) {
        if (lockType == LockMode.LOCK_PESSIMISTIC_READ || lockType == LockMode.LOCK_PESSIMISTIC_WRITE) {
            // Override with pessimistic lock
            locked = true;
        }
    }
    String statement = getStatement(table, ops, locked);
    try {
        ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
        SQLController sqlControl = storeMgr.getSQLController();
        try {
            PreparedStatement ps = sqlControl.getStatementForQuery(mconn, statement);
            try {
                // Provide the primary key field(s)
                for (int i = 0; i < ops.length; i++) {
                    if (cmd.getIdentityType() == IdentityType.DATASTORE) {
                        StatementMappingIndex datastoreIdx = mappingDefinitions[i].getMappingForMemberPosition(SurrogateColumnType.DATASTORE_ID.getFieldNumber());
                        for (int j = 0; j < datastoreIdx.getNumberOfParameterOccurrences(); j++) {
                            table.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false).setObject(ec, ps, datastoreIdx.getParameterPositionsForOccurrence(j), ops[i].getInternalObjectId());
                        }
                    } else if (cmd.getIdentityType() == IdentityType.APPLICATION) {
                        ops[i].provideFields(cmd.getPKMemberPositions(), new ParameterSetter(ops[i], ps, mappingDefinitions[i]));
                    }
                }
                // Execute the statement
                ResultSet rs = sqlControl.executeStatementQuery(ec, mconn, statement, ps);
                try {
                    ObjectProvider[] missingOps = processResults(rs, ops);
                    if (missingOps != null && missingOps.length > 0) {
                        NucleusObjectNotFoundException[] nfes = new NucleusObjectNotFoundException[missingOps.length];
                        for (int i = 0; i < nfes.length; i++) {
                            nfes[i] = new NucleusObjectNotFoundException("Object not found", missingOps[i].getInternalObjectId());
                        }
                        throw new NucleusObjectNotFoundException("Some objects were not found. Look at nested exceptions for details", nfes);
                    }
                } finally {
                    rs.close();
                }
            } finally {
                sqlControl.closeStatement(mconn, ps);
            }
        } finally {
            mconn.release();
        }
    } catch (SQLException sqle) {
        String msg = Localiser.msg("052220", ops[0].getObjectAsPrintable(), 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()]));
    }
}
Also used : SQLException(java.sql.SQLException) 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) SQLController(org.datanucleus.store.rdbms.SQLController) NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) ExecutionContext(org.datanucleus.ExecutionContext) ResultSet(java.sql.ResultSet) ManagedConnection(org.datanucleus.store.connection.ManagedConnection) ObjectProvider(org.datanucleus.state.ObjectProvider) ArrayList(java.util.ArrayList) List(java.util.List)

Example 17 with NucleusDataStoreException

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

the class FKArrayStore method clear.

/**
 * Method to clear the Array.
 * This is called when the container object is being deleted and the elements are to be removed (maybe for dependent field).
 * @param ownerOP The ObjectProvider
 */
public void clear(ObjectProvider ownerOP) {
    boolean deleteElements = false;
    if (ownerMemberMetaData.getArray().isDependentElement()) {
        // Elements are dependent and can't exist on their own, so delete them all
        NucleusLogger.DATASTORE.debug(Localiser.msg("056034"));
        deleteElements = true;
    } else {
        if (ownerMapping.isNullable() && orderMapping.isNullable()) {
            // Field is not dependent, and nullable so we null the FK
            NucleusLogger.DATASTORE.debug(Localiser.msg("056036"));
            deleteElements = false;
        } else {
            // Field is not dependent, and not nullable so we just delete the elements
            NucleusLogger.DATASTORE.debug(Localiser.msg("056035"));
            deleteElements = true;
        }
    }
    if (deleteElements) {
        // Make sure the field is loaded
        ownerOP.isLoaded(ownerMemberMetaData.getAbsoluteFieldNumber());
        Object[] value = (Object[]) ownerOP.provideField(ownerMemberMetaData.getAbsoluteFieldNumber());
        if (value != null && value.length > 0) {
            ownerOP.getExecutionContext().deleteObjects(value);
        }
    } else {
        boolean ownerSoftDelete = ownerOP.getClassMetaData().hasExtension(MetaData.EXTENSION_CLASS_SOFTDELETE);
        if (!ownerSoftDelete) {
            // TODO Cater for multiple element roots
            // TODO If the relation is bidirectional we need to clear the owner in the element
            String clearNullifyStmt = getClearNullifyStmt();
            try {
                ExecutionContext ec = ownerOP.getExecutionContext();
                ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
                SQLController sqlControl = storeMgr.getSQLController();
                try {
                    PreparedStatement ps = sqlControl.getStatementForUpdate(mconn, clearNullifyStmt, false);
                    try {
                        int jdbcPosition = 1;
                        jdbcPosition = BackingStoreHelper.populateOwnerInStatement(ownerOP, ec, ps, jdbcPosition, this);
                        if (relationDiscriminatorMapping != null) {
                            BackingStoreHelper.populateRelationDiscriminatorInStatement(ec, ps, jdbcPosition, this);
                        }
                        sqlControl.executeStatementUpdate(ec, mconn, clearNullifyStmt, ps, true);
                    } finally {
                        sqlControl.closeStatement(mconn, ps);
                    }
                } finally {
                    mconn.release();
                }
            } catch (SQLException e) {
                throw new NucleusDataStoreException(Localiser.msg("056013", clearNullifyStmt), e);
            }
        }
    }
}
Also used : NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) ExecutionContext(org.datanucleus.ExecutionContext) SQLException(java.sql.SQLException) ManagedConnection(org.datanucleus.store.connection.ManagedConnection) PreparedStatement(java.sql.PreparedStatement) SQLController(org.datanucleus.store.rdbms.SQLController)

Example 18 with NucleusDataStoreException

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

the class FKArrayStore method iterator.

/**
 * Accessor for an iterator for the set.
 * @param ownerOP ObjectProvider for the set.
 * @return Iterator for the set.
 */
public Iterator<E> iterator(ObjectProvider ownerOP) {
    ExecutionContext ec = ownerOP.getExecutionContext();
    if (elementInfo == null || elementInfo.length == 0) {
        return null;
    }
    // Generate the statement, and statement mapping/parameter information
    IteratorStatement iterStmt = getIteratorStatement(ownerOP.getExecutionContext(), ownerOP.getExecutionContext().getFetchPlan(), true);
    SelectStatement sqlStmt = iterStmt.getSelectStatement();
    StatementClassMapping iteratorMappingDef = iterStmt.getStatementClassMapping();
    // Input parameter(s) - the owner
    int inputParamNum = 1;
    StatementMappingIndex ownerIdx = new StatementMappingIndex(ownerMapping);
    if (sqlStmt.getNumberOfUnions() > 0) {
        // Add parameter occurrence for each union of statement
        for (int j = 0; j < sqlStmt.getNumberOfUnions() + 1; j++) {
            int[] paramPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
            for (int k = 0; k < ownerMapping.getNumberOfDatastoreMappings(); k++) {
                paramPositions[k] = inputParamNum++;
            }
            ownerIdx.addParameterOccurrence(paramPositions);
        }
    } else {
        int[] paramPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
        for (int k = 0; k < ownerMapping.getNumberOfDatastoreMappings(); k++) {
            paramPositions[k] = inputParamNum++;
        }
        ownerIdx.addParameterOccurrence(paramPositions);
    }
    StatementParameterMapping iteratorMappingParams = new StatementParameterMapping();
    iteratorMappingParams.addMappingForParameter("owner", ownerIdx);
    if (ec.getTransaction().getSerializeRead() != null && ec.getTransaction().getSerializeRead()) {
        sqlStmt.addExtension(SQLStatement.EXTENSION_LOCK_FOR_UPDATE, true);
    }
    String stmt = sqlStmt.getSQLText().toSQL();
    try {
        ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
        SQLController sqlControl = storeMgr.getSQLController();
        try {
            // Create the statement
            PreparedStatement ps = sqlControl.getStatementForQuery(mconn, stmt);
            // Set the owner
            ObjectProvider stmtOwnerOP = BackingStoreHelper.getOwnerObjectProviderForBackingStore(ownerOP);
            int numParams = ownerIdx.getNumberOfParameterOccurrences();
            for (int paramInstance = 0; paramInstance < numParams; paramInstance++) {
                ownerIdx.getMapping().setObject(ec, ps, ownerIdx.getParameterPositionsForOccurrence(paramInstance), stmtOwnerOP.getObject());
            }
            try {
                ResultSet rs = sqlControl.executeStatementQuery(ec, mconn, stmt, ps);
                try {
                    ResultObjectFactory rof = null;
                    if (elementsAreEmbedded || elementsAreSerialised) {
                        throw new NucleusException("Cannot have FK array with non-persistent objects");
                    }
                    rof = new PersistentClassROF(ec, rs, false, iteratorMappingDef, elementCmd, clr.classForName(elementType));
                    return new ArrayStoreIterator(ownerOP, rs, rof, this);
                } finally {
                    rs.close();
                }
            } finally {
                sqlControl.closeStatement(mconn, ps);
            }
        } finally {
            mconn.release();
        }
    } catch (SQLException | MappedDatastoreException e) {
        throw new NucleusDataStoreException(Localiser.msg("056006", stmt), e);
    }
}
Also used : StatementParameterMapping(org.datanucleus.store.rdbms.query.StatementParameterMapping) MappedDatastoreException(org.datanucleus.store.rdbms.exceptions.MappedDatastoreException) SQLException(java.sql.SQLException) ResultObjectFactory(org.datanucleus.store.rdbms.query.ResultObjectFactory) PreparedStatement(java.sql.PreparedStatement) StatementMappingIndex(org.datanucleus.store.rdbms.query.StatementMappingIndex) StatementClassMapping(org.datanucleus.store.rdbms.query.StatementClassMapping) SQLController(org.datanucleus.store.rdbms.SQLController) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) ExecutionContext(org.datanucleus.ExecutionContext) PersistentClassROF(org.datanucleus.store.rdbms.query.PersistentClassROF) ResultSet(java.sql.ResultSet) ManagedConnection(org.datanucleus.store.connection.ManagedConnection) ObjectProvider(org.datanucleus.state.ObjectProvider) NucleusException(org.datanucleus.exceptions.NucleusException)

Example 19 with NucleusDataStoreException

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

the class FKListStore method internalAdd.

/**
 * Internal method for adding an item to the List.
 * @param ownerOP ObjectProvider for the owner
 * @param startAt The start position
 * @param atEnd Whether to add at the end
 * @param c The Collection of elements to add.
 * @param size Current size of list (if known). -1 if not known
 * @return Whether it was successful
 */
protected boolean internalAdd(ObjectProvider ownerOP, int startAt, boolean atEnd, Collection<E> c, int size) {
    if (c == null || c.size() == 0) {
        return true;
    }
    // Check what we have persistent already
    int currentListSize = (size < 0 ? size(ownerOP) : size);
    boolean shiftingElements = true;
    if (atEnd || startAt == currentListSize) {
        shiftingElements = false;
        // Not shifting so we insert from the end
        startAt = currentListSize;
    }
    boolean elementsNeedPositioning = false;
    int position = startAt;
    Iterator elementIter = c.iterator();
    while (elementIter.hasNext()) {
        // Persist any non-persistent objects optionally at their final list position (persistence-by-reachability)
        if (shiftingElements) {
            // We have to shift things so dont bother with positioning
            position = -1;
        }
        boolean inserted = validateElementForWriting(ownerOP, elementIter.next(), position);
        if (!inserted || shiftingElements) {
            // This element wasnt positioned in the validate so we need to set the positions later
            elementsNeedPositioning = true;
        }
        if (!shiftingElements) {
            position++;
        }
    }
    if (shiftingElements) {
        // all ids after the position we insert at
        try {
            // Calculate the amount we need to shift any existing elements by
            // This is used where inserting between existing elements and have to shift down all elements after the start point
            int shift = c.size();
            ExecutionContext ec = ownerOP.getExecutionContext();
            ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
            try {
                // shift up existing elements after start position by "shift"
                for (int i = currentListSize - 1; i >= startAt; i--) {
                    // Shift the index of this row by "shift"
                    internalShift(ownerOP, mconn, true, i, shift, false);
                }
            } finally {
                mconn.release();
            }
        } catch (MappedDatastoreException e) {
            // An error was encountered during the shift process so abort here
            throw new NucleusDataStoreException(Localiser.msg("056009", e.getMessage()), e.getCause());
        }
    }
    if (shiftingElements || elementsNeedPositioning) {
        // Some elements have been shifted so the new elements need positioning now, or we already had some
        // of the new elements persistent and so they need their positions setting now
        elementIter = c.iterator();
        while (elementIter.hasNext()) {
            Object element = elementIter.next();
            updateElementFk(ownerOP, element, ownerOP.getObject(), startAt);
            startAt++;
        }
    }
    return true;
}
Also used : MappedDatastoreException(org.datanucleus.store.rdbms.exceptions.MappedDatastoreException) NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) ExecutionContext(org.datanucleus.ExecutionContext) ListIterator(java.util.ListIterator) Iterator(java.util.Iterator) ManagedConnection(org.datanucleus.store.connection.ManagedConnection)

Example 20 with NucleusDataStoreException

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

the class FKListStore method updateElementFk.

/**
 * Utility to update a foreign-key in the element in the case of a unidirectional 1-N relationship.
 * @param ownerOP ObjectProvider for the owner
 * @param element The element to update
 * @param owner The owner object to set in the FK
 * @param index The index position (or -1 if not known)
 * @return Whether it was performed successfully
 */
private boolean updateElementFk(ObjectProvider ownerOP, Object element, Object owner, int index) {
    if (element == null) {
        return false;
    }
    ExecutionContext ec = ownerOP.getExecutionContext();
    String updateFkStmt = getUpdateFkStmt(element);
    boolean retval;
    try {
        ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
        SQLController sqlControl = storeMgr.getSQLController();
        try {
            PreparedStatement ps = sqlControl.getStatementForUpdate(mconn, updateFkStmt, false);
            try {
                ComponentInfo elemInfo = getComponentInfoForElement(element);
                JavaTypeMapping ownerMapping = elemInfo.getOwnerMapping();
                JavaTypeMapping elemMapping = elemInfo.getDatastoreClass().getIdMapping();
                JavaTypeMapping orderMapping = elemInfo.getDatastoreClass().getExternalMapping(ownerMemberMetaData, MappingType.EXTERNAL_INDEX);
                int jdbcPosition = 1;
                if (owner == null) {
                    if (ownerMemberMetaData != null) {
                        ownerMapping.setObject(ec, ps, MappingHelper.getMappingIndices(jdbcPosition, ownerMapping), null, ownerOP, ownerMemberMetaData.getAbsoluteFieldNumber());
                    } else {
                        ownerMapping.setObject(ec, ps, MappingHelper.getMappingIndices(jdbcPosition, ownerMapping), null);
                    }
                    jdbcPosition += ownerMapping.getNumberOfDatastoreMappings();
                } else {
                    jdbcPosition = BackingStoreHelper.populateOwnerInStatement(ownerOP, ec, ps, jdbcPosition, this);
                }
                if (orderMapping != null) {
                    jdbcPosition = BackingStoreHelper.populateOrderInStatement(ec, ps, index, jdbcPosition, orderMapping);
                }
                if (relationDiscriminatorMapping != null) {
                    jdbcPosition = BackingStoreHelper.populateRelationDiscriminatorInStatement(ec, ps, jdbcPosition, this);
                }
                jdbcPosition = BackingStoreHelper.populateElementForWhereClauseInStatement(ec, ps, element, jdbcPosition, elemMapping);
                sqlControl.executeStatementUpdate(ec, mconn, updateFkStmt, ps, true);
                retval = true;
            } finally {
                sqlControl.closeStatement(mconn, ps);
            }
        } finally {
            mconn.release();
        }
    } catch (SQLException e) {
        throw new NucleusDataStoreException(Localiser.msg("056027", updateFkStmt), e);
    }
    return retval;
}
Also used : NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) ExecutionContext(org.datanucleus.ExecutionContext) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) SQLException(java.sql.SQLException) ManagedConnection(org.datanucleus.store.connection.ManagedConnection) PreparedStatement(java.sql.PreparedStatement) SQLController(org.datanucleus.store.rdbms.SQLController)

Aggregations

NucleusDataStoreException (org.datanucleus.exceptions.NucleusDataStoreException)288 SQLException (java.sql.SQLException)185 ExecutionContext (org.datanucleus.ExecutionContext)139 ManagedConnection (org.datanucleus.store.connection.ManagedConnection)131 PreparedStatement (java.sql.PreparedStatement)128 SQLController (org.datanucleus.store.rdbms.SQLController)126 ResultSet (java.sql.ResultSet)73 Iterator (java.util.Iterator)43 StatementMappingIndex (org.datanucleus.store.rdbms.query.StatementMappingIndex)38 CollectionAddOperation (org.datanucleus.flush.CollectionAddOperation)34 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)33 ArrayList (java.util.ArrayList)32 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)30 Collection (java.util.Collection)27 CollectionRemoveOperation (org.datanucleus.flush.CollectionRemoveOperation)26 StatementClassMapping (org.datanucleus.store.rdbms.query.StatementClassMapping)24 List (java.util.List)23 ObjectProvider (org.datanucleus.state.ObjectProvider)22 SelectStatement (org.datanucleus.store.rdbms.sql.SelectStatement)22 MappedDatastoreException (org.datanucleus.store.rdbms.exceptions.MappedDatastoreException)21