public void updateObjectForWriteWithChangeSet() {
WriteObjectQuery writeQuery = getWriteObjectQuery();
ObjectChangeSet changeSet = writeQuery.getObjectChangeSet();
Object object = writeQuery.getObject();
ClassDescriptor descriptor = getDescriptor();
DescriptorQueryManager queryManager = descriptor.getQueryManager();
AbstractSession session = getSession();
CommitManager commitManager = session.getCommitManager();
// check for user-defined query
if ((!writeQuery.isUserDefined())// this is not a user-defined query
&& queryManager.hasUpdateQuery()// there is a user-defined query
&& isExpressionQueryMechanism()) {// this is not a hand-coded call (custom SQL etc.)
// This must be done here because the user defined update does not use a changeset so it will not be set otherwise
commitManager.markPreModifyCommitInProgress(object);
performUserDefinedUpdate();
return;
}
// This must be done after the custom query check, otherwise it will be done twice.
commitManager.markPreModifyCommitInProgress(object);
DescriptorEventManager eventManager = descriptor.getEventManager();
if (changeSet.hasChanges()) {
// PERF: Avoid events if no listeners.
if (eventManager.hasAnyEventListeners()) {
DescriptorEvent event = new DescriptorEvent(DescriptorEventManager.PreUpdateWithChangesEvent, writeQuery);
eventManager.executeEvent(event);
// PreUpdateWithChangesEvent listeners may have altered the object - should recalculate the change set.
UnitOfWorkChangeSet uowChangeSet = (UnitOfWorkChangeSet)((UnitOfWorkImpl)session).getUnitOfWorkChangeSet();
if (!uowChangeSet.isChangeSetFromOutsideUOW()){
// writeQuery.getObjectChangeSet() is mapped to object in uowChangeSet.
// It is first cleared then re-populated by calculateChanges method.
if (!descriptor.getObjectChangePolicy().isAttributeChangeTrackingPolicy() ){
writeQuery.getObjectChangeSet().clear();
}
if (descriptor.getObjectChangePolicy().calculateChangesForExistingObject(object, uowChangeSet, ((UnitOfWorkImpl)session), descriptor, false) == null) {
// calculateChanges returns null in case the changeSet doesn't have changes.
// It should be removed from the list of ObjectChangeSets that have changes in uowChangeSet.
uowChangeSet.getAllChangeSets().remove(writeQuery.getObjectChangeSet());
}
}
}
}
// Verify if deep shallow modify is turned on
if (writeQuery.shouldCascadeParts()) {
queryManager.preUpdate(writeQuery);
}
// The row must not be built until after preUpdate in case the object reference has changed.
// For a user defined update in the uow to row must be built twice to check if any update is required.
writeQuery.setModifyRow(descriptor.getObjectBuilder().buildRowForUpdateWithChangeSet(writeQuery));
Boolean shouldModifyVersionField = changeSet.shouldModifyVersionField();
if (!getModifyRow().isEmpty() || (shouldModifyVersionField != null) || changeSet.hasCmpPolicyForcedUpdate()) {
// If user defined the entire row is required. Must not be built until change is known.
if (writeQuery.isUserDefined() || writeQuery.isCallQuery()) {
writeQuery.setModifyRow(descriptor.getObjectBuilder().buildRow(object, session));
}
OptimisticLockingPolicy lockingPolicy = descriptor.getOptimisticLockingPolicy();
// Update the write lock field if required.
if (lockingPolicy != null) {
lockingPolicy.addLockValuesToTranslationRow(writeQuery);
if (!getModifyRow().isEmpty() || shouldModifyVersionField.booleanValue()) {
// Update the row with newer lock value.
lockingPolicy.updateRowAndObjectForUpdate(writeQuery, object);
} else if (!shouldModifyVersionField.booleanValue() && (lockingPolicy instanceof VersionLockingPolicy)) {
// Add the existing write lock value to the for a "read" lock (requires something to update).
((VersionLockingPolicy)lockingPolicy).writeLockValueIntoRow(writeQuery, object);
}
}
// PERF: Avoid events if no listeners.
if (eventManager.hasAnyEventListeners()) {
DescriptorEvent event = new DescriptorEvent(DescriptorEventManager.AboutToUpdateEvent, writeQuery);
event.setRecord(getModifyRow());
eventManager.executeEvent(event);
}
if (QueryMonitor.shouldMonitor()) {
QueryMonitor.incrementUpdate(getWriteObjectQuery());
}
int rowCount = updateObject().intValue();
if (rowCount < 1) {
session.getEventManager().noRowsModified(writeQuery, object);
}
if (lockingPolicy != null) {
lockingPolicy.validateUpdate(rowCount, object, writeQuery);
}
}
commitManager.markPostModifyCommitInProgress(object);
// Verify if deep shallow modify is turned on
if (writeQuery.shouldCascadeParts()) {
queryManager.postUpdate(writeQuery);
}
if ((descriptor.getHistoryPolicy() != null) && descriptor.getHistoryPolicy().shouldHandleWrites()) {
descriptor.getHistoryPolicy().postUpdate(writeQuery);
}