Search in sources :

Example 26 with DNStateManager

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

the class ArrayMapping method postInsert.

// ---------------------- Implementation of MappingCallbacks ----------------------------------
/**
 * Method to be called after the insert of the owner class element.
 * @param ownerSM StateManager of the owner
 */
public void postInsert(DNStateManager ownerSM) {
    ExecutionContext ec = ownerSM.getExecutionContext();
    Object value = ownerSM.provideField(getAbsoluteFieldNumber());
    if (value == null) {
        return;
    }
    if (containerIsStoredInSingleColumn()) {
        if (mmd.getArray().elementIsPersistent()) {
            // Make sure all persistable elements have StateManagers
            Object[] arrElements = (Object[]) value;
            for (Object elem : arrElements) {
                if (elem != null) {
                    DNStateManager elemSM = ec.findStateManager(elem);
                    if (elemSM == null || ec.getApiAdapter().getExecutionContext(elem) == null) {
                        elemSM = ec.getNucleusContext().getStateManagerFactory().newForEmbedded(ec, elem, false, ownerSM, mmd.getAbsoluteFieldNumber(), PersistableObjectType.EMBEDDED_ARRAY_ELEMENT_PC);
                    }
                }
            }
        }
        return;
    }
    int arrayLength = Array.getLength(value);
    boolean persistentElements = (mmd.getRelationType(ec.getClassLoaderResolver()) != RelationType.NONE);
    boolean needsAttaching = false;
    if (persistentElements) {
        Object[] array = (Object[]) value;
        if (!mmd.isCascadePersist()) {
            // Check that all elements are persistent before continuing and throw exception if necessary
            if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
                NucleusLogger.PERSISTENCE.debug(Localiser.msg("007006", mmd.getFullFieldName()));
            }
            for (int i = 0; i < arrayLength; i++) {
                if (!ec.getApiAdapter().isDetached(array[i]) && !ec.getApiAdapter().isPersistent(array[i])) {
                    // Element is not persistent so throw exception
                    throw new ReachableObjectNotCascadedException(mmd.getFullFieldName(), array[i]);
                }
            }
        } else {
            // Reachability
            if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
                NucleusLogger.PERSISTENCE.debug(Localiser.msg("007007", IdentityUtils.getPersistableIdentityForId(ownerSM.getInternalObjectId()), mmd.getFullFieldName()));
            }
        }
        for (int i = 0; i < arrayLength; i++) {
            if (ec.getApiAdapter().isDetached(array[i])) {
                needsAttaching = true;
                break;
            }
        }
    }
    if (needsAttaching) {
        // Create a wrapper and attach the elements (and add the others)
        SCO collWrapper = replaceFieldWithWrapper(ownerSM, null);
        if (arrayLength > 0) {
            collWrapper.attachCopy(value);
            // The attach will have put entries in the operationQueue if using optimistic, so flush them
            ec.flushOperationsForBackingStore(((BackedSCO) collWrapper).getBackingStore(), ownerSM);
        }
    } else {
        if (arrayLength > 0) {
            // Add the elements direct to the datastore
            ((ArrayStore) storeMgr.getBackingStoreForField(ec.getClassLoaderResolver(), mmd, null)).set(ownerSM, value);
        }
    }
}
Also used : ExecutionContext(org.datanucleus.ExecutionContext) DNStateManager(org.datanucleus.state.DNStateManager) ArrayStore(org.datanucleus.store.types.scostore.ArrayStore) SCO(org.datanucleus.store.types.SCO) BackedSCO(org.datanucleus.store.types.wrappers.backed.BackedSCO) ReachableObjectNotCascadedException(org.datanucleus.exceptions.ReachableObjectNotCascadedException)

Example 27 with DNStateManager

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

the class PersistentClassROF method findObjectWithIdAndLoadFields.

/**
 * Method to lookup an object for an id, and specify its FieldValues using the ResultSet. Works for all identity types.
 * @param id The identity (DatastoreId, Application id, or SCOID when nondurable)
 * @param membersToLoad Absolute numbers of members to load
 * @param membersToStore Absolute numbers of members to store in StateManager (for later)
 * @param pcClass The class of the required object if known
 * @param cmd Metadata for the type
 * @param surrogateVersion The version when the object has a surrogate version field
 * @return The persistable object for this id
 */
private T findObjectWithIdAndLoadFields(final Object id, final int[] membersToLoad, final int[] membersToStore, Class pcClass, final AbstractClassMetaData cmd, final Object surrogateVersion) {
    return (T) ec.findObject(id, new FieldValues() {

        // TODO If we ever support just loading a FK value but not instantiating this needs to store the value in StateManager.
        public void fetchFields(DNStateManager sm) {
            resultSetGetter.setStateManager(sm);
            sm.replaceFields(membersToLoad, resultSetGetter, false);
            // Set version
            if (surrogateVersion != null) {
                // Surrogate version field
                sm.setVersion(surrogateVersion);
            } else if (cmd.getVersionMetaData() != null && cmd.getVersionMetaData().getMemberName() != null) {
                // Version stored in a normal field
                VersionMetaData vermd = cmd.getVersionMetaData();
                int versionFieldNumber = rootCmd.getMetaDataForMember(vermd.getMemberName()).getAbsoluteFieldNumber();
                if (resultMapping.getMappingForMemberPosition(versionFieldNumber) != null) {
                    Object verFieldValue = sm.provideField(versionFieldNumber);
                    if (verFieldValue != null) {
                        sm.setVersion(verFieldValue);
                    }
                }
            }
            if (membersToStore != null) {
                for (int i = 0; i < membersToStore.length; i++) {
                    StatementMappingIndex mapIdx = mappingDefinition.getMappingForMemberPosition(membersToStore[i]);
                    JavaTypeMapping m = mapIdx.getMapping();
                    if (m instanceof PersistableMapping) {
                        // 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 to null and don't bother saving the value
                            sm.replaceField(membersToStore[i], null);
                        } else {
                            // Store the "id" value in case the member is ever accessed
                            sm.storeFieldValue(membersToStore[i], memberId);
                        }
                    }
                }
            }
        }

        public void fetchNonLoadedFields(DNStateManager sm) {
            resultSetGetter.setStateManager(sm);
            // TODO Use membersToStore here?
            sm.replaceNonLoadedFields(membersToLoad, resultSetGetter);
        }

        public FetchPlan getFetchPlanForLoading() {
            return fp;
        }
    }, pcClass, ignoreCache, false);
}
Also used : PersistableMapping(org.datanucleus.store.rdbms.mapping.java.PersistableMapping) VersionMetaData(org.datanucleus.metadata.VersionMetaData) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) DNStateManager(org.datanucleus.state.DNStateManager) FieldValues(org.datanucleus.store.FieldValues) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData)

Example 28 with DNStateManager

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

the class LocateBulkRequest method processResults.

private DNStateManager[] processResults(ResultSet rs, DNStateManager[] sms) throws SQLException {
    List<DNStateManager> missingSMs = new ArrayList<>();
    for (int i = 0; i < sms.length; i++) {
        missingSMs.add(sms[i]);
    }
    ExecutionContext ec = sms[0].getExecutionContext();
    while (rs.next()) {
        FieldManager resultFM = new ResultSetGetter(ec, rs, resultMapping, cmd);
        Object id = null;
        Object key = null;
        if (cmd.getIdentityType() == IdentityType.DATASTORE) {
            StatementMappingIndex idx = resultMapping.getMappingForMemberPosition(SurrogateColumnType.DATASTORE_ID.getFieldNumber());
            JavaTypeMapping idMapping = idx.getMapping();
            key = idMapping.getObject(ec, rs, idx.getColumnPositions());
            if (IdentityUtils.isDatastoreIdentity(key)) {
                // If mapping is OIDMapping then returns an OID rather than the column value
                key = IdentityUtils.getTargetKeyForDatastoreIdentity(key);
            }
        } else if (cmd.getIdentityType() == IdentityType.APPLICATION) {
            if (cmd.usesSingleFieldIdentityClass()) {
                int[] pkFieldNums = cmd.getPKMemberPositions();
                AbstractMemberMetaData pkMmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkFieldNums[0]);
                if (pkMmd.getType() == int.class) {
                    key = resultFM.fetchIntField(pkFieldNums[0]);
                } else if (pkMmd.getType() == short.class) {
                    key = resultFM.fetchShortField(pkFieldNums[0]);
                } else if (pkMmd.getType() == long.class) {
                    key = resultFM.fetchLongField(pkFieldNums[0]);
                } else if (pkMmd.getType() == char.class) {
                    key = resultFM.fetchCharField(pkFieldNums[0]);
                } else if (pkMmd.getType() == boolean.class) {
                    key = resultFM.fetchBooleanField(pkFieldNums[0]);
                } else if (pkMmd.getType() == byte.class) {
                    key = resultFM.fetchByteField(pkFieldNums[0]);
                } else if (pkMmd.getType() == double.class) {
                    key = resultFM.fetchDoubleField(pkFieldNums[0]);
                } else if (pkMmd.getType() == float.class) {
                    key = resultFM.fetchFloatField(pkFieldNums[0]);
                } else if (pkMmd.getType() == String.class) {
                    key = resultFM.fetchStringField(pkFieldNums[0]);
                } else {
                    key = resultFM.fetchObjectField(pkFieldNums[0]);
                }
            } else {
                id = IdentityUtils.getApplicationIdentityForResultSetRow(ec, cmd, null, true, resultFM);
            }
        }
        // Find which StateManager this row is for
        DNStateManager sm = null;
        for (DNStateManager missingSM : missingSMs) {
            Object opId = missingSM.getInternalObjectId();
            if (cmd.getIdentityType() == IdentityType.DATASTORE) {
                Object opKey = IdentityUtils.getTargetKeyForDatastoreIdentity(opId);
                if (key != null && opKey.getClass() != key.getClass()) {
                    opKey = TypeConversionHelper.convertTo(opKey, key.getClass());
                }
                if (opKey.equals(key)) {
                    sm = missingSM;
                    break;
                }
            } else if (cmd.getIdentityType() == IdentityType.APPLICATION) {
                if (cmd.usesSingleFieldIdentityClass()) {
                    Object opKey = IdentityUtils.getTargetKeyForSingleFieldIdentity(opId);
                    if (opKey.equals(key)) {
                        sm = missingSM;
                        break;
                    }
                } else {
                    if (opId.equals(id)) {
                        sm = missingSM;
                        break;
                    }
                }
            }
        }
        if (sm != null) {
            // Mark StateManager as processed
            missingSMs.remove(sm);
            // Load up any unloaded fields that we have selected
            int[] selectedMemberNums = resultMapping.getMemberNumbers();
            int[] unloadedMemberNums = ClassUtils.getFlagsSetTo(sm.getLoadedFields(), selectedMemberNums, false);
            if (unloadedMemberNums != null && unloadedMemberNums.length > 0) {
                sm.replaceFields(unloadedMemberNums, resultFM);
            }
            // Load version if present and not yet set
            JavaTypeMapping versionMapping = table.getSurrogateMapping(SurrogateColumnType.VERSION, false);
            if (sm.getTransactionalVersion() == null && versionMapping != null) {
                VersionMetaData currentVermd = table.getVersionMetaData();
                Object datastoreVersion = null;
                if (currentVermd != null) {
                    if (currentVermd.getMemberName() == null) {
                        // Surrogate version
                        // Why use true now?
                        versionMapping = table.getSurrogateMapping(SurrogateColumnType.VERSION, true);
                        StatementMappingIndex verIdx = resultMapping.getMappingForMemberPosition(SurrogateColumnType.VERSION.getFieldNumber());
                        datastoreVersion = versionMapping.getObject(ec, rs, verIdx.getColumnPositions());
                    } else {
                        datastoreVersion = sm.provideField(cmd.getAbsolutePositionOfMember(currentVermd.getMemberName()));
                    }
                    sm.setVersion(datastoreVersion);
                }
            }
        }
    }
    if (!missingSMs.isEmpty()) {
        return missingSMs.toArray(new DNStateManager[missingSMs.size()]);
    }
    return null;
}
Also used : FieldManager(org.datanucleus.store.fieldmanager.FieldManager) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) VersionMetaData(org.datanucleus.metadata.VersionMetaData) ArrayList(java.util.ArrayList) StatementMappingIndex(org.datanucleus.store.rdbms.query.StatementMappingIndex) ResultSetGetter(org.datanucleus.store.rdbms.fieldmanager.ResultSetGetter) ExecutionContext(org.datanucleus.ExecutionContext) DNStateManager(org.datanucleus.state.DNStateManager) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 29 with DNStateManager

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

the class LocateBulkRequest method execute.

/**
 * Method performing the location of the records in the datastore.
 * @param sms StateManagers to be located
 * @throws NucleusObjectNotFoundException with nested exceptions for each of missing objects (if any)
 */
public void execute(DNStateManager[] sms) {
    if (sms == null || sms.length == 0) {
        return;
    }
    if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
        // Debug information about what we are retrieving
        StringBuilder str = new StringBuilder();
        for (int i = 0; i < sms.length; i++) {
            if (i > 0) {
                str.append(", ");
            }
            str.append(sms[i].getInternalObjectId());
        }
        NucleusLogger.PERSISTENCE.debug(Localiser.msg("052223", str.toString(), table));
    }
    ExecutionContext ec = sms[0].getExecutionContext();
    RDBMSStoreManager storeMgr = table.getStoreManager();
    AbstractClassMetaData cmd = sms[0].getClassMetaData();
    // Override with pessimistic lock where specified
    LockMode lockType = ec.getLockManager().getLockMode(sms[0].getInternalObjectId());
    boolean locked = (lockType == LockMode.LOCK_PESSIMISTIC_READ || lockType == LockMode.LOCK_PESSIMISTIC_WRITE) ? true : ec.getSerializeReadForClass(cmd.getFullClassName());
    String statement = getStatement(table, sms, 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 < sms.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), sms[i].getInternalObjectId());
                        }
                    } else if (cmd.getIdentityType() == IdentityType.APPLICATION) {
                        sms[i].provideFields(cmd.getPKMemberPositions(), new ParameterSetter(sms[i], ps, mappingDefinitions[i]));
                    }
                }
                // Execute the statement
                ResultSet rs = sqlControl.executeStatementQuery(ec, mconn, statement, ps);
                try {
                    DNStateManager[] missingSMs = processResults(rs, sms);
                    if (missingSMs != null && missingSMs.length > 0) {
                        NucleusObjectNotFoundException[] nfes = new NucleusObjectNotFoundException[missingSMs.length];
                        for (int i = 0; i < nfes.length; i++) {
                            nfes[i] = new NucleusObjectNotFoundException(Localiser.msg("050018", IdentityUtils.getPersistableIdentityForId(missingSMs[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", sms[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) ArrayList(java.util.ArrayList) List(java.util.List) DNStateManager(org.datanucleus.state.DNStateManager)

Example 30 with DNStateManager

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

the class OracleSerialisedPCMapping method performSetPostProcessing.

/**
 * Retrieve the empty BLOB created by the insert statement and write out the current BLOB field value to the Oracle BLOB object
 * @param ownerSM the current StateManager
 */
public void performSetPostProcessing(DNStateManager ownerSM) {
    Object value = ownerSM.provideField(mmd.getAbsoluteFieldNumber());
    DNStateManager sm = null;
    if (value != null) {
        ExecutionContext ec = ownerSM.getExecutionContext();
        sm = ec.findStateManager(value);
        if (sm == null || sm.getExecutionContext().getApiAdapter().getExecutionContext(value) == null) {
            // Assign a StateManager to the serialised object since none present
            sm = ec.getNucleusContext().getStateManagerFactory().newForEmbedded(ec, value, false, ownerSM, mmd.getAbsoluteFieldNumber(), PersistableObjectType.EMBEDDED_PC);
        }
    }
    if (sm != null) {
        sm.setStoringPC();
    }
    // 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
    if (columnMappings[0] instanceof ColumnMappingPostSet) {
        ((ColumnMappingPostSet) columnMappings[0]).setPostProcessing(ownerSM, bytes);
    }
    if (sm != null) {
        sm.unsetStoringPC();
    }
}
Also used : ExecutionContext(org.datanucleus.ExecutionContext) DNStateManager(org.datanucleus.state.DNStateManager) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) ObjectOutputStream(java.io.ObjectOutputStream) ColumnMappingPostSet(org.datanucleus.store.rdbms.mapping.column.ColumnMappingPostSet)

Aggregations

DNStateManager (org.datanucleus.state.DNStateManager)64 ExecutionContext (org.datanucleus.ExecutionContext)38 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)22 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)20 SQLException (java.sql.SQLException)17 StatementMappingIndex (org.datanucleus.store.rdbms.query.StatementMappingIndex)16 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)15 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)15 ManagedConnection (org.datanucleus.store.connection.ManagedConnection)14 StatementClassMapping (org.datanucleus.store.rdbms.query.StatementClassMapping)14 NucleusDataStoreException (org.datanucleus.exceptions.NucleusDataStoreException)13 SQLController (org.datanucleus.store.rdbms.SQLController)13 PreparedStatement (java.sql.PreparedStatement)12 ResultSet (java.sql.ResultSet)10 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)9 NucleusException (org.datanucleus.exceptions.NucleusException)9 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)9 Collection (java.util.Collection)8 ArrayList (java.util.ArrayList)7 RelationType (org.datanucleus.metadata.RelationType)7