Search in sources :

Example 56 with DNStateManager

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

the class ExpressionUtils method getValueForMemberOfObject.

/**
 * Get the value of a managed field/property in the provided object.
 * @param ec execution context
 * @param mmd metadata for the field/property
 * @param object the pc object
 * @return The field value
 */
public static Object getValueForMemberOfObject(ExecutionContext ec, AbstractMemberMetaData mmd, Object object) {
    if (ec == null) {
        // Transient or detached maybe
        return ClassUtils.getValueOfFieldByReflection(object, mmd.getName());
    // TODO What if this is a property?
    }
    DNStateManager sm = ec.findStateManager(object);
    if (!mmd.isPrimaryKey()) {
        // Make sure the field is loaded
        sm.isLoaded(mmd.getAbsoluteFieldNumber());
    }
    FieldManager fm = new SingleValueFieldManager();
    sm.provideFields(new int[] { mmd.getAbsoluteFieldNumber() }, fm);
    return fm.fetchObjectField(mmd.getAbsoluteFieldNumber());
}
Also used : SingleValueFieldManager(org.datanucleus.store.fieldmanager.SingleValueFieldManager) FieldManager(org.datanucleus.store.fieldmanager.FieldManager) SingleValueFieldManager(org.datanucleus.store.fieldmanager.SingleValueFieldManager) DNStateManager(org.datanucleus.state.DNStateManager)

Example 57 with DNStateManager

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

the class OracleClobColumnMapping method setPostProcessing.

@SuppressWarnings("deprecation")
@Override
public void setPostProcessing(DNStateManager sm, Object value) {
    String stringValue = (String) value;
    ExecutionContext ec = sm.getExecutionContext();
    Table table = column.getTable();
    RDBMSStoreManager storeMgr = table.getStoreManager();
    if (table instanceof DatastoreClass) {
        // CLOB within a primary table
        DatastoreClass classTable = (DatastoreClass) table;
        // Generate "SELECT {clobColumn} 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);
        sqlStmt.select(blobSqlTbl, column, null);
        StatementClassMapping mappingDefinition = new StatementClassMapping();
        AbstractClassMetaData cmd = sm.getClassMetaData();
        SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
        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.getNumberOfColumnMappings()];
                for (int j = 0; j < pkMapping.getNumberOfColumnMappings(); j++) {
                    inputParams[j] = inputParamNum++;
                }
                pkIdx.addParameterOccurrence(inputParams);
            }
        }
        String textStmt = sqlStmt.getSQLText().toSQL();
        if (sm.isEmbedded()) {
            // This mapping is embedded, so navigate back to the real owner since that is the "id" in the table
            DNStateManager embeddedOwner = ec.getOwnerForEmbeddedStateManager(sm);
            if (embeddedOwner != null) {
                // TODO Should check if the owner is stored in this table
                sm = embeddedOwner;
            }
        }
        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), sm.getInternalObjectId());
                        }
                    } else if (cmd.getIdentityType() == IdentityType.APPLICATION) {
                        sm.provideFields(cmd.getPKMemberPositions(), new ParameterSetter(sm, ps, mappingDefinition));
                    }
                    ResultSet rs = sqlControl.executeStatementQuery(ec, mconn, textStmt, ps);
                    try {
                        if (!rs.next()) {
                            throw new NucleusObjectNotFoundException(Localiser.msg("050018", IdentityUtils.getPersistableIdentityForId(sm.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 CLOB type
                            oracle.sql.CLOB clob = (oracle.sql.CLOB) rs.getClob(1);
                            if (clob != null) {
                                // Deprecated but what can you do
                                clob.putString(1, stringValue);
                            }
                        } else {
                            // Oracle JDBC drivers 10 and above supposedly use the JDBC standard class for Clobs
                            java.sql.Clob clob = rs.getClob(1);
                            if (clob != null) {
                                clob.setString(1, stringValue);
                            }
                        }
                    } finally {
                        rs.close();
                    }
                } finally {
                    sqlControl.closeStatement(mconn, ps);
                }
            } finally {
                mconn.release();
            }
        } catch (SQLException e) {
            throw new NucleusDataStoreException("Update of CLOB value failed: " + textStmt, e);
        }
    } else {
        // TODO Support join table
        throw new NucleusDataStoreException("We do not support INSERT/UPDATE CLOB post processing of non-primary table " + table);
    }
}
Also used : SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) 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) ManagedConnection(org.datanucleus.store.connection.ManagedConnection) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) Table(org.datanucleus.store.rdbms.table.Table) PreparedStatement(java.sql.PreparedStatement) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) StatementClassMapping(org.datanucleus.store.rdbms.query.StatementClassMapping) ExecutionContext(org.datanucleus.ExecutionContext) DatastoreAdapter(org.datanucleus.store.rdbms.adapter.DatastoreAdapter) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) DNStateManager(org.datanucleus.state.DNStateManager) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 58 with DNStateManager

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

the class ResultSetGetter method fetchObjectField.

public Object fetchObjectField(int fieldNumber) {
    StatementMappingIndex mapIdx = resultMappings.getMappingForMemberPosition(fieldNumber);
    JavaTypeMapping mapping = mapIdx.getMapping();
    AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber);
    RelationType relationType = mmd.getRelationType(ec.getClassLoaderResolver());
    Object value;
    if (mapping instanceof EmbeddedPCMapping || mapping instanceof SerialisedPCMapping || mapping instanceof SerialisedReferenceMapping) {
        value = mapping.getObject(ec, rs, mapIdx.getColumnPositions(), sm, fieldNumber);
    } else {
        if (mmd.isSingleCollection()) {
            StatementClassMapping relationMappings = resultMappings.getMappingDefinitionForMemberPosition(fieldNumber);
            if (relationMappings != null) {
                Class type = ec.getClassLoaderResolver().classForName(mmd.getCollection().getElementType());
                value = processSubObjectFields(mapping, type, relationMappings);
                ElementContainerHandler containerHandler = ec.getTypeManager().getContainerHandler(mmd.getType());
                value = containerHandler.newContainer(mmd, value);
            } else {
                value = mapping.getObject(ec, rs, mapIdx.getColumnPositions());
            }
        } else if (RelationType.isRelationSingleValued(relationType)) {
            // Process fields of sub-object if available in this result set
            StatementClassMapping relationMappings = resultMappings.getMappingDefinitionForMemberPosition(fieldNumber);
            if (relationMappings != null) {
                value = processSubObjectFields(mapping, mmd.getType(), relationMappings);
            } else {
                value = mapping.getObject(ec, rs, mapIdx.getColumnPositions());
            }
        } else {
            value = mapping.getObject(ec, rs, mapIdx.getColumnPositions());
        }
    }
    if (sm != null) {
        if (relationType == RelationType.ONE_TO_ONE_BI && value != null) {
            // Store the value at the other side of the 1-1 BI for use later if required
            DNStateManager otherSM = ec.findStateManager(value);
            if (otherSM != null) {
                AbstractMemberMetaData[] relMmds = mmd.getRelatedMemberMetaData(ec.getClassLoaderResolver());
                if (!otherSM.isFieldLoaded(relMmds[0].getAbsoluteFieldNumber()) && relMmds[0].getType().isAssignableFrom(sm.getObject().getClass())) {
                    otherSM.storeFieldValue(relMmds[0].getAbsoluteFieldNumber(), sm.getExternalObjectId());
                }
            }
        }
        if (cmd.getSCOMutableMemberFlags()[fieldNumber]) {
            // Wrap any SCO mutable fields
            return SCOUtils.wrapSCOField(sm, fieldNumber, value, false);
        } else if (RelationType.isRelationSingleValued(relationType) && (mmd.getEmbeddedMetaData() != null && mmd.getEmbeddedMetaData().getOwnerMember() != null)) {
            // Embedded PC, so make sure the field is wrapped where appropriate TODO This should be part of ManagedRelationships
            sm.updateOwnerFieldInEmbeddedField(fieldNumber, value);
            return value;
        }
    }
    return value;
}
Also used : JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) SerialisedReferenceMapping(org.datanucleus.store.rdbms.mapping.java.SerialisedReferenceMapping) EmbeddedPCMapping(org.datanucleus.store.rdbms.mapping.java.EmbeddedPCMapping) StatementMappingIndex(org.datanucleus.store.rdbms.query.StatementMappingIndex) StatementClassMapping(org.datanucleus.store.rdbms.query.StatementClassMapping) RelationType(org.datanucleus.metadata.RelationType) SerialisedPCMapping(org.datanucleus.store.rdbms.mapping.java.SerialisedPCMapping) DNStateManager(org.datanucleus.state.DNStateManager) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) ElementContainerHandler(org.datanucleus.store.types.containers.ElementContainerHandler)

Example 59 with DNStateManager

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

the class InsertRequest method execute.

/**
 * Method performing the insertion of the record from the datastore.
 * Takes the constructed insert query and populates with the specific record information.
 * @param sm StateManager for the record to be inserted
 */
public void execute(DNStateManager sm) {
    ExecutionContext ec = sm.getExecutionContext();
    if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
        // Debug information about what we are inserting
        NucleusLogger.PERSISTENCE.debug(Localiser.msg("052207", sm.getObjectAsPrintable(), table));
    }
    try {
        VersionMetaData vermd = table.getVersionMetaData();
        RDBMSStoreManager storeMgr = table.getStoreManager();
        if (vermd != null && vermd.getMemberName() != null) {
            // Version field - Update the version in the object
            AbstractMemberMetaData verfmd = ((AbstractClassMetaData) vermd.getParent()).getMetaDataForMember(vermd.getMemberName());
            Object currentVersion = sm.getVersion();
            if (currentVersion instanceof Number) {
                // Cater for Integer based versions
                currentVersion = Long.valueOf(((Number) currentVersion).longValue());
            }
            Object nextOptimisticVersion = ec.getLockManager().getNextVersion(vermd, currentVersion);
            if (verfmd.getType() == Integer.class || verfmd.getType() == int.class) {
                // Cater for Integer based versions
                nextOptimisticVersion = Integer.valueOf(((Number) nextOptimisticVersion).intValue());
            }
            sm.replaceField(verfmd.getAbsoluteFieldNumber(), nextOptimisticVersion);
        }
        // Set the state to "inserting" (may already be at this state if multiple inheritance level INSERT)
        sm.setInserting();
        // sm.changeActivityState(ActivityState.INSERTING);
        SQLController sqlControl = storeMgr.getSQLController();
        ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
        try {
            List<String> pkColumnNames = new ArrayList<>();
            if (table.getIdentityType() == IdentityType.DATASTORE) {
                JavaTypeMapping mapping = table.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, true);
                ColumnMapping[] columnMappings = mapping.getColumnMappings();
                pkColumnNames = Stream.of(columnMappings).map(cm -> cm.getColumn().getIdentifier().getName()).collect(toList());
            } else if (table.getIdentityType() == IdentityType.APPLICATION) {
                List<Column> pkColumns = ((AbstractClassTable) table).getPrimaryKey().getColumns();
                if (!pkColumns.isEmpty()) {
                    pkColumnNames = pkColumns.stream().map(cm -> cm.getName()).collect(toList());
                }
            }
            PreparedStatement ps = sqlControl.getStatementForUpdate(mconn, insertStmt, batch, hasIdentityColumn && storeMgr.getDatastoreAdapter().supportsOption(DatastoreAdapter.GET_GENERATED_KEYS_STATEMENT), pkColumnNames);
            try {
                StatementClassMapping mappingDefinition = new StatementClassMapping();
                for (int i = 0; i < stmtMappings.length; i++) {
                    if (stmtMappings[i] != null) {
                        mappingDefinition.addMappingForMember(i, stmtMappings[i]);
                    }
                }
                // Provide the primary key field(s)
                if (table.getIdentityType() == IdentityType.DATASTORE) {
                    if (!table.isObjectIdDatastoreAttributed() || !table.isBaseDatastoreClass()) {
                        int[] paramNumber = { IDPARAMNUMBER };
                        table.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false).setObject(ec, ps, paramNumber, sm.getInternalObjectId());
                    }
                } else if (table.getIdentityType() == IdentityType.APPLICATION) {
                    if (pkFieldNumbers != null && pkFieldNumbers.length > 0) {
                        sm.provideFields(pkFieldNumbers, new ParameterSetter(sm, ps, mappingDefinition));
                    }
                }
                // Provide all non-key fields needed for the insert - provides "persistence-by-reachability" for these fields
                if (insertFieldNumbers.length > 0) {
                    AbstractClassMetaData cmd = sm.getClassMetaData();
                    if (createTimestampStmtMapping != null) {
                        // Set create timestamp to time for the start of this transaction
                        int createTimestampMemberPos = cmd.getCreateTimestampMemberPosition();
                        AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(createTimestampMemberPos);
                        if (mmd.getType().isAssignableFrom(java.time.Instant.class)) {
                            sm.replaceField(createTimestampMemberPos, ec.getTransaction().getIsActive() ? java.time.Instant.ofEpochMilli(ec.getTransaction().getBeginTime()) : java.time.Instant.now());
                        } else {
                            sm.replaceField(createTimestampMemberPos, ec.getTransaction().getIsActive() ? new Timestamp(ec.getTransaction().getBeginTime()) : new Timestamp(System.currentTimeMillis()));
                        }
                    }
                    if (createUserStmtMapping != null) {
                        // Set create user to current user
                        sm.replaceField(cmd.getCreateUserMemberPosition(), ec.getCurrentUser());
                    }
                    int numberOfFieldsToProvide = 0;
                    int numMembers = cmd.getMemberCount();
                    for (int i = 0; i < insertFieldNumbers.length; i++) {
                        if (insertFieldNumbers[i] < numMembers) {
                            numberOfFieldsToProvide++;
                        }
                    }
                    int j = 0;
                    int[] fieldNums = new int[numberOfFieldsToProvide];
                    for (int i = 0; i < insertFieldNumbers.length; i++) {
                        if (insertFieldNumbers[i] < numMembers) {
                            fieldNums[j++] = insertFieldNumbers[i];
                        }
                    }
                    sm.provideFields(fieldNums, new ParameterSetter(sm, ps, mappingDefinition));
                }
                JavaTypeMapping versionMapping = table.getSurrogateMapping(SurrogateColumnType.VERSION, false);
                if (versionMapping != null) {
                    // Surrogate version - set the new version for the object
                    Object currentVersion = sm.getVersion();
                    Object nextOptimisticVersion = ec.getLockManager().getNextVersion(vermd, currentVersion);
                    for (int k = 0; k < versionStmtMapping.getNumberOfParameterOccurrences(); k++) {
                        versionMapping.setObject(ec, ps, versionStmtMapping.getParameterPositionsForOccurrence(k), nextOptimisticVersion);
                    }
                    sm.setTransactionalVersion(nextOptimisticVersion);
                } else if (vermd != null && vermd.getMemberName() != null) {
                    // Version field - set the new version for the object
                    Object currentVersion = sm.getVersion();
                    Object nextOptimisticVersion = ec.getLockManager().getNextVersion(vermd, currentVersion);
                    sm.setTransactionalVersion(nextOptimisticVersion);
                }
                if (multitenancyStmtMapping != null) {
                    // Multitenancy mapping
                    String tenantId = ec.getTenantId();
                    if (tenantId == null) {
                        NucleusLogger.PERSISTENCE.warn("Insert of object with multitenancy column but tenantId not set! Suggest that you set it.");
                    }
                    table.getSurrogateMapping(SurrogateColumnType.MULTITENANCY, false).setObject(ec, ps, multitenancyStmtMapping.getParameterPositionsForOccurrence(0), tenantId);
                }
                if (softDeleteStmtMapping != null) {
                    // Soft-Delete mapping
                    table.getSurrogateMapping(SurrogateColumnType.SOFTDELETE, false).setObject(ec, ps, softDeleteStmtMapping.getParameterPositionsForOccurrence(0), Boolean.FALSE);
                }
                if (createUserStmtMapping != null) {
                    table.getSurrogateMapping(SurrogateColumnType.CREATE_USER, false).setObject(ec, ps, createUserStmtMapping.getParameterPositionsForOccurrence(0), ec.getCurrentUser());
                }
                if (createTimestampStmtMapping != null) {
                    table.getSurrogateMapping(SurrogateColumnType.CREATE_TIMESTAMP, false).setObject(ec, ps, createTimestampStmtMapping.getParameterPositionsForOccurrence(0), new Timestamp(ec.getTransaction().getIsActive() ? ec.getTransaction().getBeginTime() : System.currentTimeMillis()));
                }
                if (updateUserStmtMapping != null) {
                    // TODO Do we need to specify this on INSERT? can they be nullable?
                    table.getSurrogateMapping(SurrogateColumnType.UPDATE_USER, false).setObject(ec, ps, updateUserStmtMapping.getParameterPositionsForOccurrence(0), "");
                }
                if (updateTimestampStmtMapping != null) {
                    // TODO Do we need to specify this on INSERT? can they be nullable?
                    table.getSurrogateMapping(SurrogateColumnType.UPDATE_TIMESTAMP, false).setObject(ec, ps, updateTimestampStmtMapping.getParameterPositionsForOccurrence(0), null);
                }
                JavaTypeMapping discrimMapping = table.getSurrogateMapping(SurrogateColumnType.DISCRIMINATOR, false);
                if (discrimMapping != null) {
                    // Discriminator mapping
                    Object discVal = sm.getClassMetaData().getDiscriminatorValue();
                    for (int k = 0; k < discriminatorStmtMapping.getNumberOfParameterOccurrences(); k++) {
                        discrimMapping.setObject(ec, ps, discriminatorStmtMapping.getParameterPositionsForOccurrence(k), discVal);
                    }
                }
                // External FK columns (optional)
                if (externalFKStmtMappings != null) {
                    for (int i = 0; i < externalFKStmtMappings.length; i++) {
                        Object fkValue = sm.getAssociatedValue(externalFKStmtMappings[i].getMapping());
                        if (fkValue != null) {
                            // Need to provide the owner field number so PCMapping can work out if it is inserted yet
                            AbstractMemberMetaData ownerFmd = table.getMetaDataForExternalMapping(externalFKStmtMappings[i].getMapping(), MappingType.EXTERNAL_FK);
                            for (int k = 0; k < externalFKStmtMappings[i].getNumberOfParameterOccurrences(); k++) {
                                externalFKStmtMappings[i].getMapping().setObject(ec, ps, externalFKStmtMappings[i].getParameterPositionsForOccurrence(k), fkValue, null, ownerFmd.getAbsoluteFieldNumber());
                            }
                        } else {
                            // We're inserting a null so don't need the owner field
                            for (int k = 0; k < externalFKStmtMappings[i].getNumberOfParameterOccurrences(); k++) {
                                externalFKStmtMappings[i].getMapping().setObject(ec, ps, externalFKStmtMappings[i].getParameterPositionsForOccurrence(k), null);
                            }
                        }
                    }
                }
                // External FK discriminator columns (optional)
                if (externalFKDiscrimStmtMappings != null) {
                    for (int i = 0; i < externalFKDiscrimStmtMappings.length; i++) {
                        Object discrimValue = sm.getAssociatedValue(externalFKDiscrimStmtMappings[i].getMapping());
                        for (int k = 0; k < externalFKDiscrimStmtMappings[i].getNumberOfParameterOccurrences(); k++) {
                            externalFKDiscrimStmtMappings[i].getMapping().setObject(ec, ps, externalFKDiscrimStmtMappings[i].getParameterPositionsForOccurrence(k), discrimValue);
                        }
                    }
                }
                // External order columns (optional)
                if (externalOrderStmtMappings != null) {
                    for (int i = 0; i < externalOrderStmtMappings.length; i++) {
                        Object orderValue = sm.getAssociatedValue(externalOrderStmtMappings[i].getMapping());
                        if (orderValue == null) {
                            // No order value so use -1
                            orderValue = Integer.valueOf(-1);
                        }
                        for (int k = 0; k < externalOrderStmtMappings[i].getNumberOfParameterOccurrences(); k++) {
                            externalOrderStmtMappings[i].getMapping().setObject(ec, ps, externalOrderStmtMappings[i].getParameterPositionsForOccurrence(k), orderValue);
                        }
                    }
                }
                sqlControl.executeStatementUpdate(ec, mconn, insertStmt, ps, !batch);
                if (hasIdentityColumn) {
                    // Identity column was set in the datastore using auto-increment/identity/serial etc
                    Object newId = getInsertedIdentityValue(ec, sqlControl, sm, mconn, ps);
                    sm.setPostStoreNewObjectId(newId);
                    if (NucleusLogger.DATASTORE_PERSIST.isDebugEnabled()) {
                        NucleusLogger.DATASTORE_PERSIST.debug(Localiser.msg("052206", sm.getObjectAsPrintable(), IdentityUtils.getPersistableIdentityForId(sm.getInternalObjectId())));
                    }
                }
                // Execute any mapping actions on the insert of the fields (e.g Oracle CLOBs/BLOBs)
                if (postSetMappings != null) {
                    for (JavaTypeMapping m : postSetMappings) {
                        if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
                            NucleusLogger.PERSISTENCE.debug(Localiser.msg("052222", sm.getObjectAsPrintable(), m.getMemberMetaData().getFullFieldName()));
                        }
                        m.performSetPostProcessing(sm);
                    }
                }
                // Update the insert status for this table via the StoreManager
                storeMgr.setObjectIsInsertedToLevel(sm, table);
                // (if we did it the other way around we would get a NotYetFlushedException thrown above).
                for (int i = 0; i < relationFieldNumbers.length; i++) {
                    Object value = sm.provideField(relationFieldNumbers[i]);
                    if (value != null && ec.getApiAdapter().isDetached(value)) {
                        Object valueAttached = ec.persistObjectInternal(value, null, -1, PersistableObjectType.PC);
                        sm.replaceField(relationFieldNumbers[i], valueAttached);
                    }
                }
                // Perform reachability on all fields that have no datastore column (1-1 bi non-owner, N-1 bi join)
                if (reachableFieldNumbers.length > 0) {
                    int numberOfReachableFields = 0;
                    for (int i = 0; i < reachableFieldNumbers.length; i++) {
                        if (reachableFieldNumbers[i] < sm.getClassMetaData().getMemberCount()) {
                            numberOfReachableFields++;
                        }
                    }
                    int[] fieldNums = new int[numberOfReachableFields];
                    int j = 0;
                    for (int i = 0; i < reachableFieldNumbers.length; i++) {
                        if (reachableFieldNumbers[i] < sm.getClassMetaData().getMemberCount()) {
                            fieldNums[j++] = reachableFieldNumbers[i];
                        }
                    }
                    mappingDefinition = new StatementClassMapping();
                    for (int i = 0; i < retrievedStmtMappings.length; i++) {
                        if (retrievedStmtMappings[i] != null) {
                            mappingDefinition.addMappingForMember(i, retrievedStmtMappings[i]);
                        }
                    }
                    NucleusLogger.PERSISTENCE.debug("Performing reachability on fields " + StringUtils.intArrayToString(fieldNums));
                    sm.provideFields(fieldNums, new ParameterSetter(sm, ps, mappingDefinition));
                }
            } finally {
                sqlControl.closeStatement(mconn, ps);
            }
        } finally {
            mconn.release();
        }
    } catch (SQLException e) {
        String msg = Localiser.msg("052208", sm.getObjectAsPrintable(), insertStmt, e.getMessage());
        NucleusLogger.DATASTORE_PERSIST.warn(msg);
        List<Exception> exceptions = new ArrayList<>();
        exceptions.add(e);
        while ((e = e.getNextException()) != null) {
            exceptions.add(e);
        }
        throw new NucleusDataStoreException(msg, exceptions.toArray(new Throwable[exceptions.size()]));
    }
    // Execute any mapping actions now that we have inserted the element (things like inserting any association parent-child).
    if (mappingCallbacks != null) {
        for (MappingCallbacks m : mappingCallbacks) {
            try {
                if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
                    NucleusLogger.PERSISTENCE.debug(Localiser.msg("052209", IdentityUtils.getPersistableIdentityForId(sm.getInternalObjectId()), ((JavaTypeMapping) m).getMemberMetaData().getFullFieldName()));
                }
                m.postInsert(sm);
            } catch (NotYetFlushedException e) {
                sm.updateFieldAfterInsert(e.getPersistable(), ((JavaTypeMapping) m).getMemberMetaData().getAbsoluteFieldNumber());
            }
        }
    }
}
Also used : ParameterSetter(org.datanucleus.store.rdbms.fieldmanager.ParameterSetter) MappingConsumer(org.datanucleus.store.rdbms.mapping.MappingConsumer) StatementMappingIndex(org.datanucleus.store.rdbms.query.StatementMappingIndex) SurrogateColumnType(org.datanucleus.store.schema.table.SurrogateColumnType) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) DatastoreIdentifier(org.datanucleus.store.rdbms.identifier.DatastoreIdentifier) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) Localiser(org.datanucleus.util.Localiser) ColumnMapping(org.datanucleus.store.rdbms.mapping.column.ColumnMapping) ResultSet(java.sql.ResultSet) Map(java.util.Map) MetaData(org.datanucleus.metadata.MetaData) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) NucleusException(org.datanucleus.exceptions.NucleusException) Timestamp(java.sql.Timestamp) PreparedStatement(java.sql.PreparedStatement) SQLController(org.datanucleus.store.rdbms.SQLController) List(java.util.List) Stream(java.util.stream.Stream) IdentityUtils(org.datanucleus.identity.IdentityUtils) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) IdentityType(org.datanucleus.metadata.IdentityType) DNStateManager(org.datanucleus.state.DNStateManager) AbstractClassTable(org.datanucleus.store.rdbms.table.AbstractClassTable) PersistableObjectType(org.datanucleus.PersistableObjectType) StringUtils(org.datanucleus.util.StringUtils) MappingCallbacks(org.datanucleus.store.rdbms.mapping.MappingCallbacks) VersionMetaData(org.datanucleus.metadata.VersionMetaData) ExecutionContext(org.datanucleus.ExecutionContext) HashMap(java.util.HashMap) PersistableMapping(org.datanucleus.store.rdbms.mapping.java.PersistableMapping) ArrayList(java.util.ArrayList) SQLException(java.sql.SQLException) NucleusLogger(org.datanucleus.util.NucleusLogger) MetaDataUtils(org.datanucleus.metadata.MetaDataUtils) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) DatastoreAdapter(org.datanucleus.store.rdbms.adapter.DatastoreAdapter) Column(org.datanucleus.store.rdbms.table.Column) StatementClassMapping(org.datanucleus.store.rdbms.query.StatementClassMapping) Iterator(java.util.Iterator) NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) ColumnMetaData(org.datanucleus.metadata.ColumnMetaData) MappingType(org.datanucleus.store.rdbms.mapping.MappingType) Collectors.toList(java.util.stream.Collectors.toList) ManagedConnection(org.datanucleus.store.connection.ManagedConnection) RelationType(org.datanucleus.metadata.RelationType) SecondaryTable(org.datanucleus.store.rdbms.table.SecondaryTable) NotYetFlushedException(org.datanucleus.exceptions.NotYetFlushedException) ReferenceMapping(org.datanucleus.store.rdbms.mapping.java.ReferenceMapping) VersionMetaData(org.datanucleus.metadata.VersionMetaData) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) SQLException(java.sql.SQLException) MappingCallbacks(org.datanucleus.store.rdbms.mapping.MappingCallbacks) ArrayList(java.util.ArrayList) ParameterSetter(org.datanucleus.store.rdbms.fieldmanager.ParameterSetter) Timestamp(java.sql.Timestamp) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) SQLController(org.datanucleus.store.rdbms.SQLController) NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) ManagedConnection(org.datanucleus.store.connection.ManagedConnection) List(java.util.List) ArrayList(java.util.ArrayList) Collectors.toList(java.util.stream.Collectors.toList) ColumnMapping(org.datanucleus.store.rdbms.mapping.column.ColumnMapping) PreparedStatement(java.sql.PreparedStatement) NotYetFlushedException(org.datanucleus.exceptions.NotYetFlushedException) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) StatementClassMapping(org.datanucleus.store.rdbms.query.StatementClassMapping) ExecutionContext(org.datanucleus.ExecutionContext) AbstractClassTable(org.datanucleus.store.rdbms.table.AbstractClassTable) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 60 with DNStateManager

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

the class QueryToSQLMapper method getValueForObjectField.

/**
 * Convenience method to return the value of a field of the supplied object.
 * If the object is null then returns null for the field.
 * @param obj The object
 * @param fieldName The field name
 * @return The field value
 */
protected Object getValueForObjectField(Object obj, String fieldName) {
    if (obj != null) {
        Object paramFieldValue = null;
        if (ec.getApiAdapter().isPersistable(obj)) {
            DNStateManager paramSM = ec.findStateManager(obj);
            AbstractClassMetaData paramCmd = ec.getMetaDataManager().getMetaDataForClass(obj.getClass(), clr);
            AbstractMemberMetaData paramFieldMmd = paramCmd.getMetaDataForMember(fieldName);
            if (paramSM != null) {
                paramSM.isLoaded(paramFieldMmd.getAbsoluteFieldNumber());
                paramFieldValue = paramSM.provideField(paramFieldMmd.getAbsoluteFieldNumber());
            } else {
                paramFieldValue = ClassUtils.getValueOfFieldByReflection(obj, fieldName);
            }
        } else {
            paramFieldValue = ClassUtils.getValueOfFieldByReflection(obj, fieldName);
        }
        return paramFieldValue;
    }
    return null;
}
Also used : DNStateManager(org.datanucleus.state.DNStateManager) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData)

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