gt:             if (eventManager.hasAnyEventListeners()) {
context: /*******************************************************************************
   * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved.
   * This program and the accompanying materials are made available under the
   * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
   * which accompanies this distribution.
   * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
   * and the Eclipse Distribution License is available at
   * http://www.eclipse.org/org/documents/edl-v10.php.
   *
   * Contributors:
   *     Oracle - initial API and implementation from Oracle TopLink
   ******************************************************************************/
  package org.eclipse.persistence.queries;
  
  import java.util.Set;
  
  import org.eclipse.persistence.internal.sessions.AbstractRecord;
  import org.eclipse.persistence.internal.sessions.AbstractSession;
  import org.eclipse.persistence.internal.sessions.CommitManager;
  import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
  import org.eclipse.persistence.mappings.DatabaseMapping.WriteType;
  import org.eclipse.persistence.exceptions.*;
  import org.eclipse.persistence.descriptors.ClassDescriptor;
  import org.eclipse.persistence.descriptors.DescriptorEvent;
  import org.eclipse.persistence.descriptors.DescriptorEventManager;
  import org.eclipse.persistence.descriptors.DescriptorQueryManager;
  import org.eclipse.persistence.descriptors.FetchGroupManager;
  import org.eclipse.persistence.tools.profiler.QueryMonitor;
  
  /**
   * <p><b>Purpose</b>: Used for deleting objects.
   *
   * <p><b>Responsibilities</b>:
   * Extract primary key from object and delete it.
   *
   * @author Yvon Lavoie
   * @since TOPLink/Java 1.0
   */
  public class DeleteObjectQuery extends ObjectLevelModifyQuery {
      /** PERF: By default only the translation row is used for deletes, the full row can be requested for custom deletes. */
      protected boolean isFullRowRequired = false;
  
      /** Indicates whether the query should use optimistic locking. */
      protected boolean usesOptimisticLocking;
  
      public DeleteObjectQuery() {
          super();
      }
  
      public DeleteObjectQuery(Object objectToDelete) {
          this();
          setObject(objectToDelete);
      }
  
      public DeleteObjectQuery(Call call) {
          this();
          setCall(call);
      }
  
      /**
       * ADVANCED:
       * Return if the full row is required by the delete query.
       * This can be set on custom delete queries if more than the objects primary key and version is required.
       */
      public boolean isFullRowRequired()
      {
          return isFullRowRequired;
      }
  
      /**
       * ADVANCED:
       * Set if the full row is required by the delete query.
       * This can be set on custom delete queries if more than the objects primary key and version is required.
       */
      public void setIsFullRowRequired(boolean isFullRowRequired)
      {
          this.isFullRowRequired = isFullRowRequired;
      }
  
      /**
       * INTERNAL:
       * Check to see if a custom query should be used for this query.
       * This is done before the query is copied and prepared/executed.
       * null means there is none.
       */
      protected DatabaseQuery checkForCustomQuery(AbstractSession session, AbstractRecord translationRow) {
          checkDescriptor(session);
  
          // check if user defined a custom query
          DescriptorQueryManager queryManager = this.descriptor.getQueryManager();
          if ((!isCallQuery())// this is not a hand-coded (custom SQL, SDK etc.) call
                   && (!isUserDefined())// and this is not a user-defined query (in the query manager)
                   && queryManager.hasDeleteQuery()) {// and there is a user-defined query (in the query manager)
              return queryManager.getDeleteQuery();
          }
  
          return null;
      }
  
      /**
       * INTERNAL:
       * Code was moved from UnitOfWork.internalExecuteQuery
       *
       * @param unitOfWork
       * @param translationRow
       * @return
       * @throws org.eclipse.persistence.exceptions.DatabaseException
       * @throws org.eclipse.persistence.exceptions.OptimisticLockException
       */
      protected Object executeInUnitOfWorkObjectLevelModifyQuery(UnitOfWorkImpl unitOfWork, AbstractRecord translationRow) throws DatabaseException, OptimisticLockException {
          Object result = unitOfWork.processDeleteObjectQuery(this);
          if (result != null) {
              // if the above method returned something then the unit of work
              //was not writing so the object has been stored to delete later
              //so return the object.  See the above method for the cases
              //where this object will be returned.
              return result;
          }
          return super.executeInUnitOfWorkObjectLevelModifyQuery(unitOfWork, translationRow);
      }
  
      /**
       * INTERNAL:
       * Returns the specific default redirector for this query type.  There are numerous default query redirectors.
       * See ClassDescriptor for their types.
       */
      protected QueryRedirector getDefaultRedirector(){
          return descriptor.getDefaultDeleteObjectQueryRedirector();
      }
  
      /**
       * INTERNAL:
       * 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.
  