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);
}
}
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);
}
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();
}
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();
}
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()]));
}
}
Aggregations