boolean batch = false;
// TODO Set the batch flag based on whether we have no other SQL being invoked in here just our UPDATE
try
{
ManagedConnection mconn = storeMgr.getConnection(ec);
SQLController sqlControl = storeMgr.getSQLController();
try
{
// Perform the update
PreparedStatement ps = sqlControl.getStatementForUpdate(mconn, stmt, batch);
try
{
Object currentVersion = sm.getTransactionalVersion();
Object nextVersion = null;
if (versionMetaData != null)
{
// Set the next version in the object
if (versionMetaData.getFieldName() != null)
{
// Version field
AbstractMemberMetaData verfmd = cmd.getMetaDataForMember(table.getVersionMetaData().getFieldName());
if (currentVersion instanceof Number)
{
// Cater for Integer-based versions
currentVersion = Long.valueOf(((Number)currentVersion).longValue());
}
nextVersion = VersionHelper.getNextVersion(versionMetaData.getVersionStrategy(), currentVersion);
if (verfmd.getType() == Integer.class || verfmd.getType() == int.class)
{
// Cater for Integer-based versions TODO Generalise this
nextVersion = Integer.valueOf(((Long)nextVersion).intValue());
}
sm.replaceField(verfmd.getAbsoluteFieldNumber(), nextVersion);
}
else
{
// Surrogate version column
nextVersion = VersionHelper.getNextVersion(versionMetaData.getVersionStrategy(), currentVersion);
}
sm.setTransactionalVersion(nextVersion);
}
// SELECT clause - set the required fields to be updated
if (updateFieldNumbers != null)
{
StatementClassMapping mappingDefinition = new StatementClassMapping();
StatementMappingIndex[] idxs = stmtMappingDefinition.getFields();
for (int i=0;i<idxs.length;i++)
{
if (idxs[i] != null)
{
mappingDefinition.addMappingForMember(i, idxs[i]);
}
}
sm.provideFields(updateFieldNumbers,
storeMgr.getFieldManagerForStatementGeneration(sm, ps, mappingDefinition, true));
}
if (versionMetaData != null && versionMetaData.getFieldName() == null)
{
// SELECT clause - set the surrogate version column to the new version
StatementMappingIndex mapIdx = stmtMappingDefinition.getVersion();
for (int i=0;i<mapIdx.getNumberOfParameterOccurrences();i++)
{
table.getVersionMapping(false).setObject(ec, ps,
mapIdx.getParameterPositionsForOccurrence(i), nextVersion);
}
}
// WHERE clause - primary key fields
if (table.getIdentityType() == IdentityType.DATASTORE)
{
// a). datastore identity
StatementMappingIndex mapIdx = stmtMappingDefinition.getDatastoreId();
for (int i=0;i<mapIdx.getNumberOfParameterOccurrences();i++)
{
table.getDatastoreObjectIdMapping().setObject(ec, ps,
mapIdx.getParameterPositionsForOccurrence(i), sm.getInternalObjectId());
}
}
else if (table.getIdentityType() == IdentityType.APPLICATION)
{
// b). application identity
StatementClassMapping mappingDefinition = new StatementClassMapping();
StatementMappingIndex[] idxs = stmtMappingDefinition.getPrimaryKeys();
for (int i=0;i<idxs.length;i++)
{
if (idxs[i] != null)
{
mappingDefinition.addMappingForMember(i, idxs[i]);
}
}
sm.provideFields(pkFieldNumbers,
storeMgr.getFieldManagerForStatementGeneration(sm, ps, mappingDefinition, true));
}
if (optimisticChecks)
{
if (currentVersion == null)
{
// Somehow the version is not set on this object (not read in ?) so report the bug
String msg = LOCALISER.msg("052201",
sm.getInternalObjectId(), table);
NucleusLogger.PERSISTENCE.error(msg);
throw new NucleusException(msg);
}
// WHERE clause - current version discriminator
StatementMappingIndex mapIdx = stmtMappingDefinition.getVersion2();
for (int i=0;i<mapIdx.getNumberOfParameterOccurrences();i++)
{
mapIdx.getMapping().setObject(ec, ps,
mapIdx.getParameterPositionsForOccurrence(i), currentVersion);
}
}
int[] rcs = sqlControl.executeStatementUpdate(mconn, stmt, ps, !batch);
if (rcs[0] == 0 && optimisticChecks)
{
// No object updated so either object disappeared or failed optimistic version checks
// TODO Batching : when we use batching here we need to process these somehow
String msg = LOCALISER.msg("052203",
sm.toPrintableID(), sm.getInternalObjectId(),
"" + currentVersion);
NucleusLogger.PERSISTENCE.error(msg);
throw new NucleusOptimisticException(msg, sm.getObject());
}
}
finally
{
sqlControl.closeStatement(mconn, ps);
}
}
finally
{
mconn.release();
}
}
catch (SQLException e)
{
String msg = LOCALISER.msg("052215",