Search in sources :

Example 41 with ClassLoaderResolver

use of org.datanucleus.ClassLoaderResolver in project datanucleus-rdbms by datanucleus.

the class C3P0ConnectionPoolFactory method createConnectionPool.

/* (non-Javadoc)
     * @see org.datanucleus.store.rdbms.datasource.ConnectionPoolFactory#createConnectionPool(org.datanucleus.store.StoreManager)
     */
public ConnectionPool createConnectionPool(StoreManager storeMgr) {
    ClassLoaderResolver clr = storeMgr.getNucleusContext().getClassLoaderResolver(null);
    // Load the database driver
    String dbDriver = storeMgr.getConnectionDriverName();
    if (!StringUtils.isWhitespace(dbDriver)) {
        loadDriver(dbDriver, clr);
    }
    // Check the existence of the necessary pooling classes
    ClassUtils.assertClassForJarExistsInClasspath(clr, "com.mchange.v2.c3p0.DataSources", "c3p0.jar");
    String dbURL = storeMgr.getConnectionURL();
    try {
        Properties dbProps = getPropertiesForDriver(storeMgr);
        DataSource unpooled = com.mchange.v2.c3p0.DataSources.unpooledDataSource(dbURL, dbProps);
        // Apply any properties and make it a pooled DataSource
        // Note that C3P0 will always look for "c3p0.properties" at the root of the CLASSPATH
        Properties c3p0Props = new Properties();
        if (storeMgr.hasProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_MAX_STATEMENTS)) {
            int size = storeMgr.getIntProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_MAX_STATEMENTS);
            if (size >= 0) {
                c3p0Props.setProperty("maxStatementsPerConnection", "" + size);
                c3p0Props.setProperty("maxStatements", "" + size);
            }
        }
        if (storeMgr.hasProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_MAX_POOL_SIZE)) {
            int size = storeMgr.getIntProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_MAX_POOL_SIZE);
            if (size >= 0) {
                c3p0Props.setProperty("maxPoolSize", "" + size);
            }
        }
        if (storeMgr.hasProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_MIN_POOL_SIZE)) {
            int size = storeMgr.getIntProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_MIN_POOL_SIZE);
            if (size >= 0) {
                c3p0Props.setProperty("minPoolSize", "" + size);
            }
        }
        if (storeMgr.hasProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_INIT_POOL_SIZE)) {
            int size = storeMgr.getIntProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_INIT_POOL_SIZE);
            if (size >= 0) {
                c3p0Props.setProperty("initialPoolSize", "" + size);
            }
        }
        com.mchange.v2.c3p0.PooledDataSource ds = (com.mchange.v2.c3p0.PooledDataSource) com.mchange.v2.c3p0.DataSources.pooledDataSource(unpooled, c3p0Props);
        return new C3P0ConnectionPool(ds);
    } catch (SQLException sqle) {
        throw new DatastorePoolException("c3p0", dbDriver, dbURL, sqle);
    }
}
Also used : SQLException(java.sql.SQLException) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) Properties(java.util.Properties) DataSource(javax.sql.DataSource)

Example 42 with ClassLoaderResolver

use of org.datanucleus.ClassLoaderResolver in project datanucleus-rdbms by datanucleus.

the class DBCP2ConnectionPoolFactory method createConnectionPool.

/* (non-Javadoc)
     * @see org.datanucleus.store.rdbms.datasource.ConnectionPoolFactory#createConnectionPool(org.datanucleus.store.StoreManager)
     */
public ConnectionPool createConnectionPool(StoreManager storeMgr) {
    ClassLoaderResolver clr = storeMgr.getNucleusContext().getClassLoaderResolver(null);
    // Load the database driver
    String dbDriver = storeMgr.getConnectionDriverName();
    if (!StringUtils.isWhitespace(dbDriver)) {
        loadDriver(dbDriver, clr);
    }
    // Check the existence of the necessary pooling classes
    ClassUtils.assertClassForJarExistsInClasspath(clr, "org.apache.commons.pool2.ObjectPool", "commons-pool-2.x.jar");
    ClassUtils.assertClassForJarExistsInClasspath(clr, "org.apache.commons.dbcp2.ConnectionFactory", "commons-dbcp-2.x.jar");
    org.apache.commons.dbcp2.PoolingDataSource ds = null;
    org.apache.commons.pool2.impl.GenericObjectPool<org.apache.commons.dbcp2.PoolableConnection> connectionPool;
    String dbURL = storeMgr.getConnectionURL();
    try {
        // Create a factory to be used by the pool to create the connections
        Properties dbProps = getPropertiesForDriver(storeMgr);
        org.apache.commons.dbcp2.ConnectionFactory connectionFactory = new org.apache.commons.dbcp2.DriverManagerConnectionFactory(dbURL, dbProps);
        // Wrap the connections and statements with pooled variants
        org.apache.commons.dbcp2.PoolableConnectionFactory poolableCF = null;
        poolableCF = new org.apache.commons.dbcp2.PoolableConnectionFactory(connectionFactory, null);
        String testSQL = null;
        if (storeMgr.hasProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_TEST_SQL)) {
            testSQL = storeMgr.getStringProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_TEST_SQL);
            poolableCF.setValidationQuery(testSQL);
        }
        if (storeMgr.hasProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_VALIDATION_TIMEOUT)) {
            int validationTimeout = storeMgr.getIntProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_VALIDATION_TIMEOUT);
            if (validationTimeout >= 0) {
                poolableCF.setValidationQueryTimeout(validationTimeout);
            }
        }
        // Create the actual pool of connections, and apply any properties
        connectionPool = new org.apache.commons.pool2.impl.GenericObjectPool(poolableCF);
        poolableCF.setPool(connectionPool);
        if (testSQL != null) {
            connectionPool.setTestOnBorrow(true);
        }
        if (storeMgr.hasProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_MAX_IDLE)) {
            int value = storeMgr.getIntProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_MAX_IDLE);
            if (value > 0) {
                connectionPool.setMaxIdle(value);
            }
        }
        if (storeMgr.hasProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_MIN_IDLE)) {
            int value = storeMgr.getIntProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_MIN_IDLE);
            if (value > 0) {
                connectionPool.setMinIdle(value);
            }
        }
        if (storeMgr.hasProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_MAX_ACTIVE)) {
            int value = storeMgr.getIntProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_MAX_ACTIVE);
            if (value > 0) {
                connectionPool.setMaxTotal(value);
            }
        }
        if (storeMgr.hasProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_MAX_WAIT)) {
            int value = storeMgr.getIntProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_MAX_WAIT);
            if (value > 0) {
                connectionPool.setMaxWaitMillis(value);
            }
        }
        if (storeMgr.hasProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_TIME_BETWEEN_EVICTOR_RUNS_MILLIS)) {
            // how often should the evictor run (if ever, default is -1 = off)
            int value = storeMgr.getIntProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_TIME_BETWEEN_EVICTOR_RUNS_MILLIS);
            if (value > 0) {
                connectionPool.setTimeBetweenEvictionRunsMillis(value);
                // in each eviction run, evict at least a quarter of "maxIdle" connections
                int maxIdle = connectionPool.getMaxIdle();
                int numTestsPerEvictionRun = (int) Math.ceil((double) maxIdle / 4);
                connectionPool.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
            }
        }
        if (storeMgr.hasProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_MIN_EVICTABLE_IDLE_TIME_MILLIS)) {
            // how long may a connection sit idle in the pool before it may be evicted
            int value = storeMgr.getIntProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_MIN_EVICTABLE_IDLE_TIME_MILLIS);
            if (value > 0) {
                connectionPool.setMinEvictableIdleTimeMillis(value);
            }
        }
        // Create the datasource
        ds = new org.apache.commons.dbcp2.PoolingDataSource(connectionPool);
    } catch (Exception e) {
        throw new DatastorePoolException("DBCP2", dbDriver, dbURL, e);
    }
    return new DBCPConnectionPool(ds, connectionPool);
}
Also used : ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) Properties(java.util.Properties)

Example 43 with ClassLoaderResolver

use of org.datanucleus.ClassLoaderResolver in project datanucleus-rdbms by datanucleus.

the class SQLAnywhereAdapter method getCreateTableStatement.

/**
 * Returns the appropriate SQL to create the given table having the given columns. No column constraints
 * or key definitions should be included. It should return something like:
 *
 * <pre>
 * CREATE TABLE FOO ( BAR VARCHAR(30), BAZ INTEGER )
 * </pre>
 * @param table The table to create.
 * @param columns The columns of the table.
 * @param props Properties for controlling the table creation
 * @param factory Factory for identifiers
 * @return The text of the SQL statement.
 */
public String getCreateTableStatement(TableImpl table, Column[] columns, Properties props, IdentifierFactory factory) {
    StringBuilder createStmt = new StringBuilder();
    String indent = "    ";
    if (getContinuationString().length() == 0) {
        indent = "";
    }
    // CREATE TABLE with column specifiers
    createStmt.append("CREATE TABLE ").append(table.toString()).append(getContinuationString()).append("(").append(getContinuationString());
    for (int i = 0; i < columns.length; ++i) {
        if (i > 0) {
            createStmt.append(",").append(getContinuationString());
        }
        createStmt.append(indent).append(columns[i].getSQLDefinition());
    }
    // PRIMARY KEY(col[,col])
    if (supportsOption(PRIMARYKEY_IN_CREATE_STATEMENTS)) {
        PrimaryKey pk = table.getPrimaryKey();
        if (pk != null && pk.getNumberOfColumns() > 0) {
            boolean includePk = true;
            if (supportsOption(IDENTITY_PK_IN_CREATE_TABLE_COLUMN_DEF)) {
                for (Column pkCol : pk.getColumns()) {
                    if (pkCol.isIdentity()) {
                        // This column is auto-increment and is specified in the column def so ignore here
                        includePk = false;
                        break;
                    }
                }
            }
            if (includePk) {
                createStmt.append(",").append(getContinuationString());
                if (pk.getName() != null) {
                    String identifier = factory.getIdentifierInAdapterCase(pk.getName());
                    createStmt.append(indent).append("CONSTRAINT ").append(identifier).append(" ").append(pk.toString());
                } else {
                    createStmt.append(indent).append(pk.toString());
                }
            }
        }
    }
    // UNIQUE( col [,col] )
    if (supportsOption(UNIQUE_IN_END_CREATE_STATEMENTS)) {
        StringBuilder uniqueConstraintStmt = new StringBuilder();
        for (int i = 0; i < columns.length; ++i) {
            if (columns[i].isUnique()) {
                if (uniqueConstraintStmt.length() < 1) {
                    uniqueConstraintStmt.append(",").append(getContinuationString());
                    uniqueConstraintStmt.append(indent).append(" UNIQUE (");
                } else {
                    uniqueConstraintStmt.append(",");
                }
                uniqueConstraintStmt.append(columns[i].getIdentifier().toString());
            }
        }
        if (uniqueConstraintStmt.length() > 1) {
            uniqueConstraintStmt.append(")");
            createStmt.append(uniqueConstraintStmt.toString());
        }
    }
    // FOREIGN KEY(col [,col] ) REFERENCES {TBL} (col [,col])
    if (supportsOption(FK_IN_END_CREATE_STATEMENTS)) {
        StringBuilder fkConstraintStmt = new StringBuilder();
        ClassLoaderResolver clr = table.getStoreManager().getNucleusContext().getClassLoaderResolver(null);
        List<ForeignKey> fks = table.getExpectedForeignKeys(clr);
        if (fks != null && !fks.isEmpty()) {
            for (ForeignKey fk : fks) {
                // TODO Ensure that the other table exists, for now assume it does
                createStmt.append(",").append(getContinuationString());
                if (fk.getName() != null) {
                    String identifier = factory.getIdentifierInAdapterCase(fk.getName());
                    createStmt.append(indent).append("CONSTRAINT ").append(identifier).append(" ").append(fk.toString());
                } else {
                    createStmt.append(indent).append(fk.toString());
                }
            }
        }
        if (fkConstraintStmt.length() > 1) {
            createStmt.append(fkConstraintStmt.toString());
        }
    }
    // CHECK (column_identifier IN (literal[,literal]))
    if (supportsOption(CHECK_IN_END_CREATE_STATEMENTS)) {
        StringBuilder checkConstraintStmt = new StringBuilder();
        for (int i = 0; i < columns.length; ++i) {
            if (columns[i].getCheckConstraints() != null) {
                checkConstraintStmt.append(",").append(getContinuationString());
                checkConstraintStmt.append(indent).append(columns[i].getCheckConstraints());
            }
        }
        if (checkConstraintStmt.length() > 1) {
            createStmt.append(checkConstraintStmt.toString());
        }
    }
    createStmt.append(getContinuationString()).append(")");
    return createStmt.toString();
}
Also used : Column(org.datanucleus.store.rdbms.table.Column) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) PrimaryKey(org.datanucleus.store.rdbms.key.PrimaryKey) ForeignKey(org.datanucleus.store.rdbms.key.ForeignKey)

Example 44 with ClassLoaderResolver

use of org.datanucleus.ClassLoaderResolver in project datanucleus-rdbms by datanucleus.

the class LocateBulkRequest method getStatement.

protected String getStatement(DatastoreClass table, DNStateManager[] sms, boolean lock) {
    RDBMSStoreManager storeMgr = table.getStoreManager();
    ClassLoaderResolver clr = storeMgr.getNucleusContext().getClassLoaderResolver(null);
    SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
    cmd = storeMgr.getMetaDataManager().getMetaDataForClass(table.getType(), clr);
    ExecutionContext ec = sms[0].getExecutionContext();
    SelectStatement sqlStatement = new SelectStatement(storeMgr, table, null, null);
    // SELECT fields we require
    resultMapping = new StatementClassMapping();
    // a). PK fields
    if (table.getIdentityType() == IdentityType.DATASTORE) {
        JavaTypeMapping datastoreIdMapping = table.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false);
        SQLExpression expr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), datastoreIdMapping);
        int[] cols = sqlStatement.select(expr, null);
        StatementMappingIndex datastoreIdx = new StatementMappingIndex(datastoreIdMapping);
        datastoreIdx.setColumnPositions(cols);
        resultMapping.addMappingForMember(SurrogateColumnType.DATASTORE_ID.getFieldNumber(), datastoreIdx);
    } else if (table.getIdentityType() == IdentityType.APPLICATION) {
        int[] pkNums = cmd.getPKMemberPositions();
        for (int i = 0; i < pkNums.length; i++) {
            AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkNums[i]);
            JavaTypeMapping pkMapping = table.getMemberMappingInDatastoreClass(mmd);
            if (pkMapping == null) {
                pkMapping = table.getMemberMapping(mmd);
            }
            SQLExpression expr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), pkMapping);
            int[] cols = sqlStatement.select(expr, null);
            StatementMappingIndex pkIdx = new StatementMappingIndex(pkMapping);
            pkIdx.setColumnPositions(cols);
            resultMapping.addMappingForMember(mmd.getAbsoluteFieldNumber(), pkIdx);
        }
    } else {
        throw new NucleusUserException("Cannot locate objects using nondurable identity");
    }
    JavaTypeMapping verMapping = table.getSurrogateMapping(SurrogateColumnType.VERSION, false);
    if (verMapping != null) {
        VersionMetaData currentVermd = table.getVersionMetaData();
        if (currentVermd != null && currentVermd.getMemberName() == null) {
            // Surrogate version column
            SQLExpression expr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), verMapping);
            int[] cols = sqlStatement.select(expr, null);
            StatementMappingIndex mapIdx = new StatementMappingIndex(verMapping);
            mapIdx.setColumnPositions(cols);
            resultMapping.addMappingForMember(SurrogateColumnType.VERSION.getFieldNumber(), mapIdx);
        }
    }
    int[] nonPkFieldNums = cmd.getNonPKMemberPositions();
    if (nonPkFieldNums != null) {
        for (int i = 0; i < nonPkFieldNums.length; i++) {
            AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(nonPkFieldNums[i]);
            JavaTypeMapping mapping = table.getMemberMapping(mmd);
            if (mapping != null && mapping.includeInFetchStatement()) {
                if (mapping instanceof PersistableMapping) {
                    // Ignore 1-1/N-1 for now
                    continue;
                }
                SQLExpression expr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), mapping);
                int[] cols = sqlStatement.select(expr, null);
                StatementMappingIndex mapIdx = new StatementMappingIndex(mapping);
                mapIdx.setColumnPositions(cols);
                resultMapping.addMappingForMember(mmd.getAbsoluteFieldNumber(), mapIdx);
            }
        }
    }
    JavaTypeMapping multitenancyMapping = table.getSurrogateMapping(SurrogateColumnType.MULTITENANCY, false);
    if (multitenancyMapping != null) {
        // Add WHERE clause for multi-tenancy
        SQLExpression tenantExpr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), multitenancyMapping);
        String[] tenantReadIds = storeMgr.getNucleusContext().getTenantReadIds(sms[0].getExecutionContext());
        if (tenantReadIds != null && tenantReadIds.length > 0) {
            // Add IN clause with values
            SQLExpression[] readIdExprs = new SQLExpression[tenantReadIds.length];
            for (int i = 0; i < tenantReadIds.length; i++) {
                readIdExprs[i] = sqlStatement.getSQLExpressionFactory().newLiteral(sqlStatement, multitenancyMapping, tenantReadIds[i].trim());
            }
            sqlStatement.whereAnd(new InExpression(tenantExpr, readIdExprs), true);
        } else {
            // Add EQ expression for tenantId TODO Use a parameter for this and set in execution
            SQLExpression tenantVal = exprFactory.newLiteral(sqlStatement, multitenancyMapping, ec.getTenantId());
            sqlStatement.whereAnd(tenantExpr.eq(tenantVal), true);
        }
    }
    JavaTypeMapping softDeleteMapping = table.getSurrogateMapping(SurrogateColumnType.SOFTDELETE, false);
    if (softDeleteMapping != null) {
        // Add WHERE clause restricting to soft-delete unset
        SQLExpression softDeleteExpr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), softDeleteMapping);
        SQLExpression softDeleteVal = exprFactory.newLiteral(sqlStatement, softDeleteMapping, Boolean.FALSE);
        sqlStatement.whereAnd(softDeleteExpr.eq(softDeleteVal), true);
    }
    // Add WHERE clause restricting to the identities of the objects
    mappingDefinitions = new StatementClassMapping[sms.length];
    int inputParamNum = 1;
    for (int i = 0; i < sms.length; i++) {
        mappingDefinitions[i] = new StatementClassMapping();
        if (table.getIdentityType() == IdentityType.DATASTORE) {
            // Datastore identity value for input
            JavaTypeMapping datastoreIdMapping = table.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false);
            SQLExpression expr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), datastoreIdMapping);
            SQLExpression val = exprFactory.newLiteralParameter(sqlStatement, datastoreIdMapping, null, "ID");
            sqlStatement.whereOr(expr.eq(val), true);
            StatementMappingIndex datastoreIdx = new StatementMappingIndex(datastoreIdMapping);
            mappingDefinitions[i].addMappingForMember(SurrogateColumnType.DATASTORE_ID.getFieldNumber(), datastoreIdx);
            datastoreIdx.addParameterOccurrence(new int[] { inputParamNum++ });
        } else if (table.getIdentityType() == IdentityType.APPLICATION) {
            // Application identity value(s) for input
            BooleanExpression pkExpr = null;
            int[] pkNums = cmd.getPKMemberPositions();
            for (int j = 0; j < pkNums.length; j++) {
                AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkNums[j]);
                JavaTypeMapping pkMapping = table.getMemberMappingInDatastoreClass(mmd);
                if (pkMapping == null) {
                    pkMapping = table.getMemberMapping(mmd);
                }
                SQLExpression expr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), pkMapping);
                SQLExpression val = exprFactory.newLiteralParameter(sqlStatement, pkMapping, null, "PK" + j);
                BooleanExpression fieldEqExpr = expr.eq(val);
                if (pkExpr == null) {
                    pkExpr = fieldEqExpr;
                } else {
                    pkExpr = pkExpr.and(fieldEqExpr);
                }
                StatementMappingIndex pkIdx = new StatementMappingIndex(pkMapping);
                mappingDefinitions[i].addMappingForMember(mmd.getAbsoluteFieldNumber(), pkIdx);
                int[] inputParams = new int[pkMapping.getNumberOfColumnMappings()];
                for (int k = 0; k < pkMapping.getNumberOfColumnMappings(); k++) {
                    inputParams[k] = inputParamNum++;
                }
                pkIdx.addParameterOccurrence(inputParams);
            }
            if (pkExpr == null) {
                throw new NucleusException("Unable to generate PK expression for WHERE clause of locate statement");
            }
            pkExpr = (BooleanExpression) pkExpr.encloseInParentheses();
            sqlStatement.whereOr(pkExpr, true);
        }
    }
    // Generate the appropriate JDBC statement allowing for locking
    if (lock) {
        sqlStatement.addExtension(SQLStatement.EXTENSION_LOCK_FOR_UPDATE, Boolean.TRUE);
        return sqlStatement.getSQLText().toSQL();
    }
    return sqlStatement.getSQLText().toSQL();
}
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) VersionMetaData(org.datanucleus.metadata.VersionMetaData) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) InExpression(org.datanucleus.store.rdbms.sql.expression.InExpression) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) StatementMappingIndex(org.datanucleus.store.rdbms.query.StatementMappingIndex) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) StatementClassMapping(org.datanucleus.store.rdbms.query.StatementClassMapping) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) PersistableMapping(org.datanucleus.store.rdbms.mapping.java.PersistableMapping) BooleanExpression(org.datanucleus.store.rdbms.sql.expression.BooleanExpression) ExecutionContext(org.datanucleus.ExecutionContext) NucleusException(org.datanucleus.exceptions.NucleusException) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 45 with ClassLoaderResolver

use of org.datanucleus.ClassLoaderResolver in project datanucleus-rdbms by datanucleus.

the class DeleteRequest method execute.

/**
 * Method performing the deletion of the record from the datastore.
 * Takes the constructed deletion query and populates with the specific record information.
 * @param sm StateManager for the record to be deleted.
 */
public void execute(DNStateManager sm) {
    if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
        // Debug information about what we are deleting
        NucleusLogger.PERSISTENCE.debug(Localiser.msg("052210", IdentityUtils.getPersistableIdentityForId(sm.getInternalObjectId()), table));
    }
    // Process all related fields first
    // a). Delete any dependent objects
    // b). Null any non-dependent objects with FK at other side
    ClassLoaderResolver clr = sm.getExecutionContext().getClassLoaderResolver();
    Set relatedObjectsToDelete = null;
    if (mappingCallbacks != null) {
        for (MappingCallbacks m : mappingCallbacks) {
            if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
                NucleusLogger.PERSISTENCE.debug(Localiser.msg("052212", IdentityUtils.getPersistableIdentityForId(sm.getInternalObjectId()), ((JavaTypeMapping) m).getMemberMetaData().getFullFieldName()));
            }
            m.preDelete(sm);
            // Check for any dependent related 1-1 objects where we hold the FK and where the object hasn't been deleted.
            // This can happen if this DeleteRequest was triggered by delete-orphans and so the related object has to be deleted *after* this object.
            // It's likely we could do this better by using AttachFieldManager and just marking the "orphan" (i.e this object) as deleted
            // (see AttachFieldManager TODO regarding when not copying)
            JavaTypeMapping mapping = (JavaTypeMapping) m;
            AbstractMemberMetaData mmd = mapping.getMemberMetaData();
            RelationType relationType = mmd.getRelationType(clr);
            if (mmd.isDependent() && (relationType == RelationType.ONE_TO_ONE_UNI || (relationType == RelationType.ONE_TO_ONE_BI && mmd.getMappedBy() == null))) {
                try {
                    sm.isLoaded(mmd.getAbsoluteFieldNumber());
                    Object relatedPc = sm.provideField(mmd.getAbsoluteFieldNumber());
                    boolean relatedObjectDeleted = sm.getExecutionContext().getApiAdapter().isDeleted(relatedPc);
                    if (!relatedObjectDeleted) {
                        if (relatedObjectsToDelete == null) {
                            relatedObjectsToDelete = new HashSet();
                        }
                        relatedObjectsToDelete.add(relatedPc);
                    }
                } catch (// Should be XXXObjectNotFoundException but dont want to use JDO class
                Exception e) {
                }
            }
        }
    }
    // and cater for other cases, in particular persistent interfaces
    if (oneToOneNonOwnerFields != null && oneToOneNonOwnerFields.length > 0) {
        for (int i = 0; i < oneToOneNonOwnerFields.length; i++) {
            updateOneToOneBidirectionalOwnerObjectForField(sm, oneToOneNonOwnerFields[i]);
        }
    }
    // Choose the statement based on whether optimistic or not
    String stmt = null;
    ExecutionContext ec = sm.getExecutionContext();
    RDBMSStoreManager storeMgr = table.getStoreManager();
    boolean optimisticChecks = false;
    if (table.getSurrogateColumn(SurrogateColumnType.SOFTDELETE) != null) {
        stmt = softDeleteStmt;
    } else {
        optimisticChecks = (versionChecks && ec.getTransaction().getOptimistic());
        stmt = optimisticChecks ? deleteStmtOptimistic : deleteStmt;
    }
    // Process the delete of this object
    try {
        ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
        SQLController sqlControl = storeMgr.getSQLController();
        try {
            // Perform the delete
            boolean batch = true;
            if (optimisticChecks || !ec.getTransaction().isActive()) {
                // Turn OFF batching if doing optimistic checks (since we need the result of the delete)
                // or if using nontransactional writes (since we want it sending to the datastore now)
                batch = false;
            }
            PreparedStatement ps = sqlControl.getStatementForUpdate(mconn, stmt, batch);
            try {
                // provide WHERE clause field(s)
                if (cmd.getIdentityType() == IdentityType.DATASTORE) {
                    StatementMappingIndex mapIdx = mappingStatementIndex.getWhereDatastoreId();
                    for (int i = 0; i < mapIdx.getNumberOfParameterOccurrences(); i++) {
                        table.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false).setObject(ec, ps, mapIdx.getParameterPositionsForOccurrence(i), sm.getInternalObjectId());
                    }
                } else {
                    StatementClassMapping mappingDefinition = new StatementClassMapping();
                    StatementMappingIndex[] idxs = mappingStatementIndex.getWhereFields();
                    for (int i = 0; i < idxs.length; i++) {
                        if (idxs[i] != null) {
                            mappingDefinition.addMappingForMember(i, idxs[i]);
                        }
                    }
                    sm.provideFields(whereFieldNumbers, new ParameterSetter(sm, ps, mappingDefinition));
                }
                if (multitenancyStatementMapping != null) {
                    table.getSurrogateMapping(SurrogateColumnType.MULTITENANCY, false).setObject(ec, ps, multitenancyStatementMapping.getParameterPositionsForOccurrence(0), ec.getTenantId());
                }
                if (optimisticChecks) {
                    // WHERE clause - current version discriminator
                    JavaTypeMapping verMapping = mappingStatementIndex.getWhereVersion().getMapping();
                    Object currentVersion = sm.getTransactionalVersion();
                    if (currentVersion == null) {
                        // Somehow the version is not set on this object (not read in ?) so report the bug
                        String msg = Localiser.msg("052202", IdentityUtils.getPersistableIdentityForId(sm.getInternalObjectId()), table);
                        NucleusLogger.PERSISTENCE.error(msg);
                        throw new NucleusException(msg);
                    }
                    StatementMappingIndex mapIdx = mappingStatementIndex.getWhereVersion();
                    for (int i = 0; i < mapIdx.getNumberOfParameterOccurrences(); i++) {
                        verMapping.setObject(ec, ps, mapIdx.getParameterPositionsForOccurrence(i), currentVersion);
                    }
                }
                int[] rcs = sqlControl.executeStatementUpdate(ec, mconn, stmt, ps, !batch);
                if (optimisticChecks && rcs[0] == 0) {
                    // No object deleted so either object disappeared or failed optimistic version checks
                    throw new NucleusOptimisticException(Localiser.msg("052203", IdentityUtils.getPersistableIdentityForId(sm.getInternalObjectId()), "" + sm.getTransactionalVersion()), sm.getObject());
                }
                if (relatedObjectsToDelete != null && !relatedObjectsToDelete.isEmpty()) {
                    // Delete any related objects that need deleting after the delete of this object
                    Iterator iter = relatedObjectsToDelete.iterator();
                    while (iter.hasNext()) {
                        Object relatedObject = iter.next();
                        ec.deleteObjectInternal(relatedObject);
                    }
                }
            } finally {
                sqlControl.closeStatement(mconn, ps);
            }
        } finally {
            mconn.release();
        }
    } catch (SQLException e) {
        String msg = Localiser.msg("052211", IdentityUtils.getPersistableIdentityForId(sm.getInternalObjectId()), stmt, e.getMessage());
        NucleusLogger.PERSISTENCE.warn(msg);
        List exceptions = new ArrayList();
        exceptions.add(e);
        while ((e = e.getNextException()) != null) {
            exceptions.add(e);
        }
        throw new NucleusDataStoreException(msg, (Throwable[]) exceptions.toArray(new Throwable[exceptions.size()]));
    }
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) SQLException(java.sql.SQLException) MappingCallbacks(org.datanucleus.store.rdbms.mapping.MappingCallbacks) ArrayList(java.util.ArrayList) StatementMappingIndex(org.datanucleus.store.rdbms.query.StatementMappingIndex) ParameterSetter(org.datanucleus.store.rdbms.fieldmanager.ParameterSetter) SQLController(org.datanucleus.store.rdbms.SQLController) NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) RelationType(org.datanucleus.metadata.RelationType) Iterator(java.util.Iterator) ManagedConnection(org.datanucleus.store.connection.ManagedConnection) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) PreparedStatement(java.sql.PreparedStatement) SQLException(java.sql.SQLException) NucleusException(org.datanucleus.exceptions.NucleusException) NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) NucleusOptimisticException(org.datanucleus.exceptions.NucleusOptimisticException) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) StatementClassMapping(org.datanucleus.store.rdbms.query.StatementClassMapping) ExecutionContext(org.datanucleus.ExecutionContext) NucleusOptimisticException(org.datanucleus.exceptions.NucleusOptimisticException) NucleusException(org.datanucleus.exceptions.NucleusException) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Aggregations

ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)242 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)94 MetaDataManager (org.datanucleus.metadata.MetaDataManager)72 NucleusContext (org.datanucleus.NucleusContext)68 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)65 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)65 PersistenceNucleusContextImpl (org.datanucleus.PersistenceNucleusContextImpl)56 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)56 ClassMetaData (org.datanucleus.metadata.ClassMetaData)54 JPAMetaDataManager (org.datanucleus.api.jpa.metadata.JPAMetaDataManager)51 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)44 NucleusException (org.datanucleus.exceptions.NucleusException)42 PersistenceUnitMetaData (org.datanucleus.metadata.PersistenceUnitMetaData)40 SQLExpressionFactory (org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory)40 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)39 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)37 ArrayList (java.util.ArrayList)36 ExecutionContext (org.datanucleus.ExecutionContext)32 SelectStatement (org.datanucleus.store.rdbms.sql.SelectStatement)30 HashMap (java.util.HashMap)28