* Perform the work to delete an object.
* @return object - the object being deleted.
*/
public Object executeDatabaseQuery() throws DatabaseException, OptimisticLockException {
AbstractSession session = getSession();
CommitManager commitManager = session.getCommitManager();
Object object = getObject();
boolean isUnitOfWork = session.isUnitOfWork();
try {
// Check if the object has already been deleted, then no work is required.
if (commitManager.isCommitCompletedInPostOrIgnore(object)) {
return object;
}
ClassDescriptor descriptor = this.descriptor;
// Check whether the object is already being deleted,
// if it is, then there is a cycle, and the foreign keys must be nulled.
if (commitManager.isCommitInPreModify(object)) {
if (!commitManager.isShallowCommitted(object)) {
getQueryMechanism().updateForeignKeyFieldBeforeDelete();
if ((descriptor.getHistoryPolicy() != null) && descriptor.getHistoryPolicy().shouldHandleWrites()) {
descriptor.getHistoryPolicy().postUpdate(this);
}
commitManager.markShallowCommit(object);
}
return object;
}
commitManager.markPreModifyCommitInProgress(getObject());
if (!isUnitOfWork) {
session.beginTransaction();
}
DescriptorEventManager eventManager = descriptor.getEventManager();
// PERF: Avoid events if no listeners.
if (eventManager.hasAnyEventListeners()) {
// Need to run pre-delete selector if available
eventManager.executeEvent(new DescriptorEvent(DescriptorEventManager.PreDeleteEvent, this));
}
// Verify if deep shallow modify is turned on
if (shouldCascadeParts()) {
descriptor.getQueryManager().preDelete(this);
}
// Check for deletion dependencies.
if (isUnitOfWork) {
Set dependencies = ((UnitOfWorkImpl)session).getDeletionDependencies(object);
if (dependencies != null) {
for (Object dependency : dependencies) {
if (!commitManager.isCommitCompletedInPostOrIgnore(dependency)) {
ClassDescriptor dependencyDescriptor = session.getDescriptor(dependency);
// PERF: Get the descriptor query, to avoid extra query creation.
DeleteObjectQuery deleteQuery = dependencyDescriptor.getQueryManager().getDeleteQuery();
if (deleteQuery == null) {
deleteQuery = new DeleteObjectQuery();
deleteQuery.setDescriptor(dependencyDescriptor);
} else {
// Ensure original query has been prepared.
deleteQuery.checkPrepare(session, deleteQuery.getTranslationRow());
deleteQuery = (DeleteObjectQuery)deleteQuery.clone();
}
deleteQuery.setIsExecutionClone(true);
deleteQuery.setObject(dependency);
session.executeQuery(deleteQuery);
}
}
}
}
// CR#2660080 missing aboutToDelete event.
// PERF: Avoid events if no listeners.
if (eventManager.hasAnyEventListeners()) {
DescriptorEvent event = new DescriptorEvent(DescriptorEventManager.AboutToDeleteEvent, this);
event.setRecord(getModifyRow());
eventManager.executeEvent(event);
}
if (QueryMonitor.shouldMonitor()) {
QueryMonitor.incrementDelete(this);
}
int rowCount = 0;
// If the object was/will be deleted from a cascade delete constraint, ignore it.
if (isUnitOfWork && ((UnitOfWorkImpl)session).hasCascadeDeleteObjects()
&& ((UnitOfWorkImpl)session).getCascadeDeleteObjects().contains(object)) {
// Cascade delete does not check optimistic lock, assume ok.
rowCount = 1;
} else {
rowCount = getQueryMechanism().deleteObject().intValue();
}
if (rowCount < 1) {
if (session.hasEventManager()) {
session.getEventManager().noRowsModified(this, object);
}
}
if (this.usesOptimisticLocking) {
descriptor.getOptimisticLockingPolicy().validateDelete(rowCount, object, this);
}
commitManager.markPostModifyCommitInProgress(getObject());
// Verify if deep shallow modify is turned on
if (shouldCascadeParts()) {
descriptor.getQueryManager().postDelete(this);
}
if ((descriptor.getHistoryPolicy() != null) && descriptor.getHistoryPolicy().shouldHandleWrites()) {
descriptor.getHistoryPolicy().postDelete(this);
}
// PERF: Avoid events if no listeners.
if (eventManager.hasAnyEventListeners()) {
// Need to run post-delete selector if available
eventManager.executeEvent(new DescriptorEvent(DescriptorEventManager.PostDeleteEvent, this));
}
if (!isUnitOfWork) {
session.commitTransaction();
}
commitManager.markCommitCompleted(object);
// CR3510313, avoid removing aggregate collections from cache (maintain cache is false).
if (shouldMaintainCache()) {
if (isUnitOfWork) {
((UnitOfWorkImpl)session).addObjectDeletedDuringCommit(object, descriptor);
} else {
session.getIdentityMapAccessorInstance().removeFromIdentityMap(getPrimaryKey(), descriptor.getJavaClass(), descriptor, object);
}
}
return object;
} catch (RuntimeException exception) {
if (!isUnitOfWork) {
session.rollbackTransaction();
}
commitManager.markCommitCompleted(object);
throw exception;
}
}