{
// Check if read-only so update not permitted
storeMgr.assertReadOnlyForUpdateOfObject(sm);
AbstractClassMetaData acmd = sm.getClassMetaData();
ManagedConnection mconn = storeMgr.getConnection(sm.getExecutionContext());
try
{
Document doc = (Document) mconn.getConnection();
long startTime = 0;
if (NucleusLogger.DATASTORE_PERSIST.isDebugEnabled())
{
startTime = System.currentTimeMillis();
// Debug information about what fields we are updating
StringBuffer str = new StringBuffer();
for (int i=0;i<fieldNumbers.length;i++)
{
if (i > 0)
{
str.append(",");
}
str.append(acmd.getMetaDataForManagedMemberAtAbsolutePosition(fieldNumbers[i]).getName());
}
NucleusLogger.DATASTORE_PERSIST.debug(LOCALISER.msg("XML.Update.Start",
sm.toPrintableID(), sm.getInternalObjectId(), str));
}
if (acmd.getVersionMetaData() != null &&
acmd.getVersionMetaData().getVersionStrategy() != VersionStrategy.NONE)
{
// versioned object so update its version
// TODO Implement version checks
}
// Get the XPath for the objects of this class
Node classnode = getNodeForClass(doc, acmd);
// Make sure we have all fields loaded that need to be (removing the node will lose them temporarily)
sm.loadUnloadedFields();
// Remove old node and replace with new
Node node = XMLUtils.findNode(doc, sm);
node.getParentNode().removeChild(node);
JAXBRuntimeBinder.marshall(sm.getObject(), classnode, this.storeMgr.getMetaDataManager(),
sm.getExecutionContext().getClassLoaderResolver());
// Handle reachability so any reachable objects in the updated fields are also persisted
sm.provideFields(fieldNumbers, new PersistFieldManager(sm, false));
if (NucleusLogger.DATASTORE_PERSIST.isDebugEnabled())
{
NucleusLogger.DATASTORE_PERSIST.debug(LOCALISER.msg("XML.ExecutionTime",
(System.currentTimeMillis() - startTime)));
}
}
catch (Exception e)
{
throw new NucleusDataStoreException(e.getMessage(), e);
}
finally
{
mconn.release();
}
}