Search in sources :

Example 11 with ObjectProvider

use of org.datanucleus.state.ObjectProvider in project datanucleus-rdbms by datanucleus.

the class OracleCollectionMapping method postInsert.

/**
 * Retrieve the empty BLOB created by the insert statement and write out the
 * current BLOB field value to the Oracle BLOB object.
 * @param ownerOP ObjectProvider of the owner
 */
public void postInsert(ObjectProvider ownerOP) {
    if (containerIsStoredInSingleColumn()) {
        ExecutionContext ec = ownerOP.getExecutionContext();
        Collection value = (Collection) ownerOP.provideField(mmd.getAbsoluteFieldNumber());
        if (value != null) {
            if (mmd.getCollection().elementIsPersistent()) {
                // Make sure all persistable elements have ObjectProviders
                Object[] collElements = value.toArray();
                for (Object elem : collElements) {
                    if (elem != null) {
                        ObjectProvider elemOP = ec.findObjectProvider(elem);
                        if (elemOP == null || ec.getApiAdapter().getExecutionContext(elem) == null) {
                            elemOP = ec.getNucleusContext().getObjectProviderFactory().newForEmbedded(ec, elem, false, ownerOP, mmd.getAbsoluteFieldNumber());
                        }
                    }
                }
            }
        }
        // Generate the contents for the BLOB
        byte[] bytes = new byte[0];
        if (value != null) {
            try {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(baos);
                oos.writeObject(value);
                bytes = baos.toByteArray();
            } catch (IOException e1) {
            // Do Nothing
            }
        }
        // Update the BLOB
        OracleBlobRDBMSMapping.updateBlobColumn(ownerOP, getTable(), getDatastoreMapping(0), bytes);
    } else {
        super.postInsert(ownerOP);
    }
}
Also used : ExecutionContext(org.datanucleus.ExecutionContext) Collection(java.util.Collection) ObjectProvider(org.datanucleus.state.ObjectProvider) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) ObjectOutputStream(java.io.ObjectOutputStream)

Example 12 with ObjectProvider

use of org.datanucleus.state.ObjectProvider in project datanucleus-rdbms by datanucleus.

the class SerialisedReferenceMapping method setObject.

/**
 * Method to populate parameter positions in a PreparedStatement with this object
 * @param ec execution context
 * @param ps The Prepared Statement
 * @param exprIndex The parameter positions to populate
 * @param value The value of the PC to use in populating the parameter positions
 * @param ownerOP ObjectProvider for the owning object
 * @param fieldNumber field number of this object in the owning object
 */
public void setObject(ExecutionContext ec, PreparedStatement ps, int[] exprIndex, Object value, ObjectProvider ownerOP, int fieldNumber) {
    ApiAdapter api = ec.getApiAdapter();
    if (api.isPersistable(value)) {
        // Assign a StateManager to the serialised object if none present
        ObjectProvider embSM = ec.findObjectProvider(value);
        if (embSM == null || api.getExecutionContext(value) == null) {
            embSM = ec.getNucleusContext().getObjectProviderFactory().newForEmbedded(ec, value, false, ownerOP, fieldNumber);
        }
    }
    ObjectProvider sm = null;
    if (api.isPersistable(value)) {
        // Find SM for serialised PC object
        sm = ec.findObjectProvider(value);
    }
    if (sm != null) {
        sm.setStoringPC();
    }
    getDatastoreMapping(0).setObject(ps, exprIndex[0], value);
    if (sm != null) {
        sm.unsetStoringPC();
    }
}
Also used : ApiAdapter(org.datanucleus.api.ApiAdapter) ObjectProvider(org.datanucleus.state.ObjectProvider)

Example 13 with ObjectProvider

use of org.datanucleus.state.ObjectProvider 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 14 with ObjectProvider

use of org.datanucleus.state.ObjectProvider in project datanucleus-rdbms by datanucleus.

the class FKListStore method validateElementForWriting.

/**
 * Method to validate that an element is valid for writing to the datastore.
 * TODO Minimise differences to super.validateElementForWriting()
 * @param op ObjectProvider for the List
 * @param element The element to validate
 * @param index The position that the element is being stored at in the list
 * @return Whether the element was inserted
 */
protected boolean validateElementForWriting(final ObjectProvider op, final Object element, final int index) {
    final Object newOwner = op.getObject();
    ComponentInfo info = getComponentInfoForElement(element);
    final DatastoreClass elementTable;
    if (storeMgr.getNucleusContext().getMetaDataManager().isPersistentInterface(elementType)) {
        elementTable = storeMgr.getDatastoreClass(storeMgr.getNucleusContext().getMetaDataManager().getImplementationNameForPersistentInterface(elementType), clr);
    } else {
        elementTable = storeMgr.getDatastoreClass(element.getClass().getName(), clr);
    }
    final JavaTypeMapping orderMapping;
    if (info != null) {
        orderMapping = info.getDatastoreClass().getExternalMapping(ownerMemberMetaData, MappingType.EXTERNAL_INDEX);
    } else {
        orderMapping = this.orderMapping;
    }
    // Check if element is ok for use in the datastore, specifying any external mappings that may be required
    boolean inserted = super.validateElementForWriting(op.getExecutionContext(), element, new FieldValues() {

        public void fetchFields(ObjectProvider elemOP) {
            // Find the (element) table storing the FK back to the owner
            if (elementTable != null) {
                JavaTypeMapping externalFKMapping = elementTable.getExternalMapping(ownerMemberMetaData, MappingType.EXTERNAL_FK);
                if (externalFKMapping != null) {
                    // The element has an external FK mapping so set the value it needs to use in the INSERT
                    elemOP.setAssociatedValue(externalFKMapping, op.getObject());
                }
                if (relationDiscriminatorMapping != null) {
                    elemOP.setAssociatedValue(relationDiscriminatorMapping, relationDiscriminatorValue);
                }
                if (orderMapping != null && index >= 0) {
                    if (ownerMemberMetaData.getOrderMetaData() != null && ownerMemberMetaData.getOrderMetaData().getMappedBy() != null) {
                        // Order is stored in a field in the element so update it
                        // We support mapped-by fields of types int/long/Integer/Long currently
                        Object indexValue = null;
                        if (orderMapping.getMemberMetaData().getTypeName().equals(ClassNameConstants.JAVA_LANG_LONG) || orderMapping.getMemberMetaData().getTypeName().equals(ClassNameConstants.LONG)) {
                            indexValue = Long.valueOf(index);
                        } else {
                            indexValue = Integer.valueOf(index);
                        }
                        elemOP.replaceFieldMakeDirty(orderMapping.getMemberMetaData().getAbsoluteFieldNumber(), indexValue);
                    } else {
                        // Order is stored in a surrogate column so save its vaue for the element to use later
                        elemOP.setAssociatedValue(orderMapping, Integer.valueOf(index));
                    }
                }
            }
            if (ownerMemberMetaData.getMappedBy() != null) {
                // TODO This is ManagedRelations - move into RelationshipManager
                // Managed Relations : 1-N bidir, so make sure owner is correct at persist
                // TODO Support DOT notation in mappedBy
                ObjectProvider ownerHolderOP = elemOP;
                int ownerFieldNumberInHolder = -1;
                if (ownerMemberMetaData.getMappedBy().indexOf('.') > 0) {
                    AbstractMemberMetaData otherMmd = null;
                    AbstractClassMetaData otherCmd = info.getAbstractClassMetaData();
                    String remainingMappedBy = ownerMemberMetaData.getMappedBy();
                    while (remainingMappedBy.indexOf('.') > 0) {
                        int dotPosition = remainingMappedBy.indexOf('.');
                        String thisMappedBy = remainingMappedBy.substring(0, dotPosition);
                        otherMmd = otherCmd.getMetaDataForMember(thisMappedBy);
                        Object holderValueAtField = ownerHolderOP.provideField(otherMmd.getAbsoluteFieldNumber());
                        ownerHolderOP = op.getExecutionContext().findObjectProviderForEmbedded(holderValueAtField, ownerHolderOP, otherMmd);
                        remainingMappedBy = remainingMappedBy.substring(dotPosition + 1);
                        otherCmd = storeMgr.getMetaDataManager().getMetaDataForClass(otherMmd.getTypeName(), clr);
                        if (remainingMappedBy.indexOf('.') < 0) {
                            otherMmd = otherCmd.getMetaDataForMember(remainingMappedBy);
                            ownerFieldNumberInHolder = otherMmd.getAbsoluteFieldNumber();
                        }
                    }
                } else {
                    ownerFieldNumberInHolder = info.getAbstractClassMetaData().getAbsolutePositionOfMember(ownerMemberMetaData.getMappedBy());
                }
                Object currentOwner = ownerHolderOP.provideField(ownerFieldNumberInHolder);
                if (currentOwner == null) {
                    // No owner, so correct it
                    NucleusLogger.PERSISTENCE.info(Localiser.msg("056037", op.getObjectAsPrintable(), ownerMemberMetaData.getFullFieldName(), StringUtils.toJVMIDString(ownerHolderOP.getObject())));
                    ownerHolderOP.replaceFieldMakeDirty(ownerFieldNumberInHolder, newOwner);
                } else if (currentOwner != newOwner && op.getReferencedPC() == null) {
                    // Inconsistent owner, so throw exception
                    throw new NucleusUserException(Localiser.msg("056038", op.getObjectAsPrintable(), ownerMemberMetaData.getFullFieldName(), StringUtils.toJVMIDString(ownerHolderOP.getObject()), StringUtils.toJVMIDString(currentOwner)));
                }
            }
        }

        public void fetchNonLoadedFields(ObjectProvider op) {
        }

        public FetchPlan getFetchPlanForLoading() {
            return null;
        }
    });
    return inserted;
}
Also used : JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) ObjectProvider(org.datanucleus.state.ObjectProvider) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) FieldValues(org.datanucleus.store.FieldValues) FetchPlan(org.datanucleus.FetchPlan) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData)

Example 15 with ObjectProvider

use of org.datanucleus.state.ObjectProvider in project datanucleus-rdbms by datanucleus.

the class FKListStore method listIterator.

/**
 * Accessor for an iterator through the list elements.
 * @param ownerOP ObjectProvider for the owner.
 * @param startIdx The start index in the list (only for indexed lists)
 * @param endIdx The end index in the list (only for indexed lists)
 * @return The List Iterator
 */
protected ListIterator<E> listIterator(ObjectProvider ownerOP, int startIdx, int endIdx) {
    ExecutionContext ec = ownerOP.getExecutionContext();
    Transaction tx = ec.getTransaction();
    if (elementInfo == null || elementInfo.length == 0) {
        return null;
    }
    // Generate the statement. Note that this is not cached since depends on the current FetchPlan and other things
    IteratorStatement iterStmt = getIteratorStatement(ownerOP.getExecutionContext(), ec.getFetchPlan(), true, startIdx, endIdx);
    SelectStatement sqlStmt = iterStmt.getSelectStatement();
    StatementClassMapping resultMapping = 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);
    }
    if (tx.getSerializeRead() != null && tx.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 set with non-persistent objects");
                    }
                    rof = new PersistentClassROF(ec, rs, false, resultMapping, elementCmd, clr.classForName(elementType));
                    return new ListStoreIterator(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 : 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) Transaction(org.datanucleus.Transaction) 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)

Aggregations

ObjectProvider (org.datanucleus.state.ObjectProvider)160 ExecutionContext (org.datanucleus.ExecutionContext)85 Iterator (java.util.Iterator)43 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)34 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)25 Map (java.util.Map)22 NucleusDataStoreException (org.datanucleus.exceptions.NucleusDataStoreException)22 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)21 SQLException (java.sql.SQLException)17 Collection (java.util.Collection)16 ApiAdapter (org.datanucleus.api.ApiAdapter)16 NucleusObjectNotFoundException (org.datanucleus.exceptions.NucleusObjectNotFoundException)16 SCOCollectionIterator (org.datanucleus.store.types.SCOCollectionIterator)16 ArrayList (java.util.ArrayList)14 HashSet (java.util.HashSet)14 StatementMappingIndex (org.datanucleus.store.rdbms.query.StatementMappingIndex)14 NucleusException (org.datanucleus.exceptions.NucleusException)13 ManagedConnection (org.datanucleus.store.connection.ManagedConnection)13 ListIterator (java.util.ListIterator)12 SQLController (org.datanucleus.store.rdbms.SQLController)12