/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2014, 2021 IBM Corporation. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
//     10/15/2010-2.2 Guy Pelletier
//       - 322008: Improve usability of additional criteria applied to queries at the session/EM
//     06/30/2011-2.3.1 Guy Pelletier
//       - 341940: Add disable/enable allowing native queries
//     09/09/2011-2.3.1 Guy Pelletier
//       - 356197: Add new VPD type to MultitenantType
//     09/14/2011-2.3.1 Guy Pelletier
//       - 357533: Allow DDL queries to execute even when Multitenant entities are part of the PU
//     05/14/2012-2.4 Guy Pelletier
//       - 376603: Provide for table per tenant support for multitenant applications
//     08/11/2012-2.5 Guy Pelletier
//       - 393867: Named queries do not work when using EM level Table Per Tenant Multitenancy.
//     11/29/2012-2.5 Guy Pelletier
//       - 395406: Fix nightly static weave test errors
//     08/11/2014-2.5 Rick Curtis
//       - 440594: Tolerate invalid NamedQuery at EntityManager creation.
//     09/03/2015 - Will Dazey
//       - 456067: Added support for defining query timeout units
//     05/26/2016-2.7 Tomas Kraus
//       - 494610: Session Properties map should be Map<String, Object>
package org.eclipse.persistence.internal.sessions;

import java.io.Serializable;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Constructor;
import java.security.AccessController;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import java.util.concurrent.TimeUnit;

import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.config.ReferenceMode;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.DescriptorEvent;
import org.eclipse.persistence.descriptors.DescriptorQueryManager;
import org.eclipse.persistence.descriptors.TablePerMultitenantPolicy;
import org.eclipse.persistence.descriptors.invalidation.CacheInvalidationPolicy;
import org.eclipse.persistence.descriptors.partitioning.PartitioningPolicy;
import org.eclipse.persistence.exceptions.ConcurrencyException;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.EclipseLinkException;
import org.eclipse.persistence.exceptions.ExceptionHandler;
import org.eclipse.persistence.exceptions.IntegrityChecker;
import org.eclipse.persistence.exceptions.IntegrityException;
import org.eclipse.persistence.exceptions.OptimisticLockException;
import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.history.AsOfClause;
import org.eclipse.persistence.indirection.ValueHolderInterface;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.databaseaccess.Accessor;
import org.eclipse.persistence.internal.databaseaccess.Platform;
import org.eclipse.persistence.internal.descriptors.ObjectBuilder;
import org.eclipse.persistence.internal.helper.ConcurrencyManager;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.helper.QueryCounter;
import org.eclipse.persistence.internal.helper.linkedlist.ExposedNodeLinkedList;
import org.eclipse.persistence.internal.history.HistoricalSession;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.identitymaps.IdentityMapManager;
import org.eclipse.persistence.internal.indirection.DatabaseValueHolder;
import org.eclipse.persistence.internal.indirection.ProtectedValueHolder;
import org.eclipse.persistence.internal.indirection.ProxyIndirectionPolicy;
import org.eclipse.persistence.internal.localization.ExceptionLocalization;
import org.eclipse.persistence.internal.queries.JoinedAttributeManager;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
import org.eclipse.persistence.internal.security.PrivilegedGetConstructorFor;
import org.eclipse.persistence.internal.security.PrivilegedInvokeConstructor;
import org.eclipse.persistence.internal.security.PrivilegedNewInstanceFromClass;
import org.eclipse.persistence.internal.sequencing.Sequencing;
import org.eclipse.persistence.internal.sessions.cdi.DisabledInjectionManager;
import org.eclipse.persistence.internal.sessions.cdi.InjectionManager;
import org.eclipse.persistence.logging.DefaultSessionLog;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.logging.SessionLogEntry;
import org.eclipse.persistence.mappings.ForeignReferenceMapping;
import org.eclipse.persistence.mappings.foundation.AbstractTransformationMapping;
import org.eclipse.persistence.platform.database.DatabasePlatform;
import org.eclipse.persistence.platform.server.ServerPlatform;
import org.eclipse.persistence.queries.AttributeGroup;
import org.eclipse.persistence.queries.Call;
import org.eclipse.persistence.queries.DataModifyQuery;
import org.eclipse.persistence.queries.DataReadQuery;
import org.eclipse.persistence.queries.DatabaseQuery;
import org.eclipse.persistence.queries.DeleteObjectQuery;
import org.eclipse.persistence.queries.DoesExistQuery;
import org.eclipse.persistence.queries.InsertObjectQuery;
import org.eclipse.persistence.queries.JPAQueryBuilder;
import org.eclipse.persistence.queries.JPQLCall;
import org.eclipse.persistence.queries.ObjectBuildingQuery;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.queries.ReadAllQuery;
import org.eclipse.persistence.queries.ReadObjectQuery;
import org.eclipse.persistence.queries.SQLCall;
import org.eclipse.persistence.queries.UpdateObjectQuery;
import org.eclipse.persistence.queries.WriteObjectQuery;
import org.eclipse.persistence.sessions.CopyGroup;
import org.eclipse.persistence.sessions.DatabaseLogin;
import org.eclipse.persistence.sessions.ExternalTransactionController;
import org.eclipse.persistence.sessions.Login;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.sessions.SessionEventManager;
import org.eclipse.persistence.sessions.SessionProfiler;
import org.eclipse.persistence.sessions.coordination.Command;
import org.eclipse.persistence.sessions.coordination.CommandManager;
import org.eclipse.persistence.sessions.coordination.CommandProcessor;
import org.eclipse.persistence.sessions.coordination.MetadataRefreshListener;
import org.eclipse.persistence.sessions.serializers.Serializer;

/**
 * Implementation of org.eclipse.persistence.sessions.Session
 * The public interface should be used.
 * @see org.eclipse.persistence.sessions.Session
 *
 * <p>
 * <b>Purpose</b>: Define the interface and common protocol of an EclipseLink compliant session.
 * <p>
 * <b>Description</b>: The session is the primary interface into EclipseLink,
 * the application should do all of its reading and writing of objects through the session.
 * The session also manages transactions and units of work.  Normally the session
 * is passed and used by the application controller objects.  Controller objects normally
 * sit behind the GUI and perform the business processes required for the application,
 * they should perform all explicit database access and database access should be avoided from
 * the domain object model.  Do not use a globally accessible session instance, doing so does
 * not allow for multiple sessions.  Multiple sessions may required when performing things like
 * data migration or multiple database access, as well the unit of work feature requires the usage
 * of multiple session instances.  Although session is abstract, any users of its subclasses
 * should only cast the variables to Session to allow usage of any of its subclasses.
 * <p>
 * <b>Responsibilities</b>:
 *    <ul>
 *    <li> Connecting/disconnecting.
 *    <li> Reading and writing objects.
 *    <li> Transaction and unit of work support.
 *    <li> Identity maps and caching.
 *    </ul>
 * @see DatabaseSessionImpl
 */
public abstract class AbstractSession extends CoreAbstractSession<ClassDescriptor, Login, Platform, Project, SessionEventManager> implements org.eclipse.persistence.sessions.Session, CommandProcessor, Serializable, Cloneable {
    /** ExceptionHandler handles database exceptions. */
    transient protected ExceptionHandler exceptionHandler;

    /** IntegrityChecker catch all the descriptor Exceptions.  */
    transient protected IntegrityChecker integrityChecker;

    /** The project stores configuration information, such as the descriptors and login. */
    transient protected Project project;

    /** Ensure mutual exclusion of the session's transaction state across multiple threads.*/
    transient protected ConcurrencyManager transactionMutex;

    /** Manages the live object cache.*/
    protected IdentityMapAccessor identityMapAccessor;

    /** If Transactions were externally started */
    protected boolean wasJTSTransactionInternallyStarted;

    /** The connection to the data store. */
    transient protected Collection<Accessor> accessors;

    /** Allow the datasource platform to be cached. */
    transient protected Platform platform;

    /** Stores predefine reusable queries.*/
    transient protected Map<String, List<DatabaseQuery>> queries;

    /**
     * Stores predefined reusable AttributeGroups.
     */
    protected Map<String, AttributeGroup> attributeGroups;

    /** Stores predefined not yet parsed JPQL queries.*/
    protected boolean jpaQueriesProcessed = false;

    /** Resolves referential integrity on commits. */
    transient protected CommitManager commitManager;

    /** Tool that log performance information. */
    transient protected SessionProfiler profiler;

    /** Support being owned by a session broker. */
    transient protected AbstractSession broker;

    /** Used to identify a session when using the session broker. */
    protected String name;

    /** Keep track of active units of work. */
    transient protected int numberOfActiveUnitsOfWork;

    /**
     * This collection will be used to store those objects that are currently locked
     * for the clone process. It should be populated with an EclipseLinkIdentityHashMap
     */
    protected Map objectsLockedForClone;

    /** Destination for logged messages and SQL. */
    transient protected SessionLog sessionLog;

    /** When logging the name of the session is typed: class name + system hashcode. */
    transient protected String logSessionString;

    /** Stores the event listeners for this session. */
    transient protected SessionEventManager eventManager;

    /** Allow for user defined properties. */
    protected Map<String, Object> properties;

    /** Delegate that handles synchronizing a UnitOfWork with an external transaction. */
    transient protected ExternalTransactionController externalTransactionController;

    /** Last descriptor accessed, use to optimize descriptor lookup. */
    transient protected ClassDescriptor lastDescriptorAccessed;

    /** PERF: cache descriptors from project. */
    transient protected Map<Class, ClassDescriptor> descriptors;

    /** PERF: cache table per tenant descriptors needing to be initialized per EM */
    transient protected List<ClassDescriptor> tablePerTenantDescriptors;

    /** PERF: cache table per tenant queries needing to be initialized per EM */
    transient protected List<DatabaseQuery> tablePerTenantQueries;

    // bug 3078039: move EJBQL alias > descriptor map from Session to Project (MWN)

    /** Used to determine If a session is in a Broker or not */
    protected boolean isInBroker;

    /**
     * Used to connect this session to EclipseLink cluster for distributed command
     */
    transient protected CommandManager commandManager;

    /**
     * PERF: Cache the write-lock check to avoid cost of checking in every register/clone.
     */
    protected boolean shouldCheckWriteLock;

    /**
     * Determined whether changes should be propagated to an EclipseLink cluster
     */
    protected boolean shouldPropagateChanges;

    /** Used to determine If a session is in a profile or not */
    protected boolean isInProfile;

    /** PERF: Quick check if logging is OFF entirely. */
    protected boolean isLoggingOff;

    /** PERF: Allow for finalizers to be enabled, currently enables client-session finalize. */
    protected boolean isFinalizersEnabled;

    /** List of active command threads. */
    transient protected ExposedNodeLinkedList activeCommandThreads;

    /**
     * Indicates whether the session is synchronized.
     * In case external transaction controller is used isSynchronized==true means
     * the session's jta connection will be freed during external transaction callback.
     */
    protected boolean isSynchronized;

    /**
     *  Stores the default reference mode that a UnitOfWork will use when referencing
     *  managed objects.
     *  @see org.eclipse.persistence.config.ReferenceMode
     */
    protected ReferenceMode defaultReferenceMode;

    /**
     * Default pessimistic lock timeout value.
     */
    protected Integer pessimisticLockTimeoutDefault;
    
    protected TimeUnit pessimisticLockTimeoutUnitDefault;

    protected int queryTimeoutDefault;

    protected TimeUnit queryTimeoutUnitDefault;

    /** Allow a session to enable concurrent processing. */
    protected boolean isConcurrent;

    /**
     * This map will hold onto class to static metamodel class references from JPA.
     */
    protected Map<String, String> staticMetamodelClasses;

    /** temporarily holds a list of events that must be fired after the current operation completes.
     *  Initialy created for postClone events.
     */
    protected List<DescriptorEvent> deferredEvents;

    /** records that the UOW is executing deferred events.  Events could cause operations to occur that may attempt to restart the event execution.  This must be avoided*/
    protected boolean isExecutingEvents;

    /** Allow queries to be targeted at specific connection pools. */
    protected PartitioningPolicy partitioningPolicy;

    /** the MetadataRefreshListener is used with RCM to force a refresh of the metadata used within EntityManagerFactoryWrappers */
    protected MetadataRefreshListener metadatalistener;

    /** Stores the set of multitenant context properties this session requires **/
    protected Set<String> multitenantContextProperties;

    /** Store the query builder used to parse JPQL. */
    transient protected JPAQueryBuilder queryBuilder;

    /** Set the Serializer to use by default for serialization. */
    transient protected Serializer serializer;

    /** Allow CDI injection of entity listeners **/
    transient protected InjectionManager injectionManager;

    /**
     * Indicates whether ObjectLevelReadQuery should by default use ResultSet Access optimization.
    * Optimization specified by the session is ignored if incompatible with other query settings.
     */
    protected boolean shouldOptimizeResultSetAccess;

    /**
     * Indicates whether Session creation should tolerate an invalid NamedQuery. If true, an exception
     * will be thrown on .createNamedQuery(..) rather than at init time.
     */
    protected boolean tolerateInvalidJPQL = false;

    /**
     * INTERNAL:
     * Create and return a new session.
     * This should only be called if the database login information is not know at the time of creation.
     * Normally it is better to call the constructor that takes the login information as an argument
     * so that the session can initialize itself to the platform information given in the login.
     */
    protected AbstractSession() {
        this.name = "";
        this.queryTimeoutUnitDefault = DescriptorQueryManager.DefaultTimeoutUnit;
        this.pessimisticLockTimeoutUnitDefault = DescriptorQueryManager.DefaultTimeoutUnit;
        initializeIdentityMapAccessor();
        // PERF - move to lazy init (3286091)
    }

    /**
     * INTERNAL:
     * Create a blank session, used for proxy session.
     */
    protected AbstractSession(int nothing) {
    }

    /**
     * PUBLIC:
     * Create and return a new session.
     * By giving the login information on creation this allows the session to initialize itself
     * to the platform given in the login. This constructor does not return a connected session.
     * To connect the session to the database login() must be sent to it. The login(userName, password)
     * method may also be used to connect the session, this allows for the user name and password
     * to be given at login but for the other database information to be provided when the session is created.
     */
    protected AbstractSession(Login login) {
        this(new org.eclipse.persistence.sessions.Project(login));
    }

    /**
     * PUBLIC:
     * Create and return a new session.
     * This constructor does not return a connected session.
     * To connect the session to the database login() must be sent to it. The login(userName, password)
     * method may also be used to connect the session, this allows for the user name and password
     * to be given at login but for the other database information to be provided when the session is created.
     */
    protected AbstractSession(org.eclipse.persistence.sessions.Project project) {
        this();
        this.project = project;
        if (project.getDatasourceLogin() == null) {
            throw ValidationException.projectLoginIsNull(this);
        }
        // add the Project's queries as session queries
        for (DatabaseQuery query : project.getQueries()) {
            addQuery(query.getName(), query);
        }
    }

    /**
     * Return the Serializer to use by default for serialization.
     */
    @Override
    public Serializer getSerializer() {
        return serializer;
    }

    /**
     * Set the Serializer to use by default for serialization.
     */
    @Override
    public void setSerializer(Serializer serializer) {
        this.serializer = serializer;
    }

    /**
     * INTERNAL
     * Return the query builder used to parser JPQL.
     */
    public JPAQueryBuilder getQueryBuilder() {
        if (this.queryBuilder == null) {
            AbstractSession parent = getParent();
            if (parent != null) {
                this.queryBuilder = parent.getQueryBuilder();
            } else {
                this.queryBuilder = buildDefaultQueryBuilder();
            }
        }
        return this.queryBuilder;
    }

    /**
     * INTERNAL
     * Set the query builder used to parser JPQL.
     */
    public void setQueryBuilder(JPAQueryBuilder queryBuilder) {
        this.queryBuilder = queryBuilder;
    }

    /**
     * INTERNAL
     * Build the JPQL builder based on session properties.
     */
    protected JPAQueryBuilder buildDefaultQueryBuilder() {
        String queryBuilderClassName = (String)getProperty(PersistenceUnitProperties.JPQL_PARSER);
        if (queryBuilderClassName == null) {
            queryBuilderClassName = "org.eclipse.persistence.internal.jpa.jpql.HermesParser";
            //queryBuilderClassName = "org.eclipse.persistence.queries.ANTLRQueryBuilder";
        }
        String validation = (String)getProperty(PersistenceUnitProperties.JPQL_VALIDATION);
        JPAQueryBuilder builder = null;
        try {
            Class parserClass = null;
            // use class.forName() to avoid loading parser classes for JAXB
            // Use Class.forName not thread class loader to avoid class loader issues.
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                parserClass = AccessController.doPrivileged(new PrivilegedClassForName(queryBuilderClassName));
                builder = (JPAQueryBuilder)AccessController.doPrivileged(new PrivilegedNewInstanceFromClass(parserClass));
            } else {
                parserClass = PrivilegedAccessHelper.getClassForName(queryBuilderClassName);
                builder = (JPAQueryBuilder)PrivilegedAccessHelper.newInstanceFromClass(parserClass);
            }
        } catch (Exception e) {
            throw new IllegalStateException("Could not load the JPQL parser class." /* TODO: Localize string */, e);
        }
        if (validation != null) {
            builder.setValidationLevel(validation);
        }
        return builder;
    }

    /**
     * INTERNAL:
     * PERF: Used for quick turning logging ON/OFF entirely.
     * @param loggingOff Logging is turned off when <code>true</code>
     *                   and turned on when <code>false</code>.
     */
    public void setLoggingOff(final boolean loggingOff) {
        isLoggingOff = loggingOff;
    }

    /**
     * INTERNAL:
     * PERF: Used for quick check if logging is OFF entirely.
     */
    public boolean isLoggingOff() {
        return isLoggingOff;
    }

    /**
     * INTERNAL:
     * Called by a sessions queries to obtain individual query ids.
     * CR #2698903
     */
    public long getNextQueryId() {
        return QueryCounter.getCount();
    }

    /**
     * INTERNAL:
     * Return a unit of work for this session not registered with the JTS transaction.
     */
    public UnitOfWorkImpl acquireNonSynchronizedUnitOfWork() {
        return acquireNonSynchronizedUnitOfWork(null);
    }

    /**
     * INTERNAL:
     * Return a unit of work for this session not registered with the JTS transaction.
     */
    public UnitOfWorkImpl acquireNonSynchronizedUnitOfWork(ReferenceMode referenceMode) {
        setNumberOfActiveUnitsOfWork(getNumberOfActiveUnitsOfWork() + 1);
        UnitOfWorkImpl unitOfWork = new UnitOfWorkImpl(this, referenceMode);
        if (shouldLog(SessionLog.FINER, SessionLog.TRANSACTION)) {
            log(SessionLog.FINER, SessionLog.TRANSACTION, "acquire_unit_of_work_with_argument", String.valueOf(System.identityHashCode(unitOfWork)));
        }
        return unitOfWork;
    }

    /**
     * INTERNAL:
     * Constructs a HistoricalSession given a valid AsOfClause.
     */
    @Override
    public org.eclipse.persistence.sessions.Session acquireHistoricalSession(AsOfClause clause) throws ValidationException {
        if ((clause == null) || (clause.getValue() == null)) {
            throw ValidationException.cannotAcquireHistoricalSession();
        }
        if (!getProject().hasGenericHistorySupport() && !hasBroker() && ((getPlatform() == null) || !getPlatform().isOracle())) {
            throw ValidationException.historicalSessionOnlySupportedOnOracle();
        }
        return new HistoricalSession(this, clause);
    }

    /**
     * PUBLIC:
     * Return a unit of work for this session.
     * The unit of work is an object level transaction that allows
     * a group of changes to be applied as a unit.
     *
     * @see UnitOfWorkImpl
     */
    @Override
    public UnitOfWorkImpl acquireUnitOfWork() {
        UnitOfWorkImpl unitOfWork = acquireNonSynchronizedUnitOfWork(getDefaultReferenceMode());
        unitOfWork.registerWithTransactionIfRequired();

        return unitOfWork;
    }

    /**
     * PUBLIC:
     * Return a repeatable write unit of work for this session.
     * A repeatable write unit of work allows multiple writeChanges (flushes).
     *
     * @see RepeatableWriteUnitOfWork
     */
    public RepeatableWriteUnitOfWork acquireRepeatableWriteUnitOfWork(ReferenceMode referenceMode) {
        return new RepeatableWriteUnitOfWork(this, referenceMode);
    }

    /**
     * PUBLIC:
     * Return a unit of work for this session.
     * The unit of work is an object level transaction that allows
     * a group of changes to be applied as a unit.
     *
     * @see UnitOfWorkImpl
     * @param referenceMode The reference type the UOW should use internally when
     * referencing Working clones.  Setting this to WEAK means the UOW will use
     * weak references to reference clones that support active object change
     * tracking and hard references for deferred change tracked objects.
     * Setting to FORCE_WEAK means that all objects will be referenced by weak
     * references and if the application no longer references the clone the
     * clone may be garbage collected.  If the clone
     * has uncommitted changes then those changes will be lost.
     */
    @Override
    public UnitOfWorkImpl acquireUnitOfWork(ReferenceMode referenceMode) {
        UnitOfWorkImpl unitOfWork = acquireNonSynchronizedUnitOfWork(referenceMode);
        unitOfWork.registerWithTransactionIfRequired();

        return unitOfWork;
    }
   /**
     * PUBLIC:
     * Add an alias for the descriptor
     */
    public void addAlias(String alias, ClassDescriptor descriptor) {
        project.addAlias(alias, descriptor);
    }

    /**
     * INTERNAL:
     * Return all pre-defined not yet parsed EJBQL queries.
     */
    @Override
    public void addJPAQuery(DatabaseQuery query) {
        getProject().addJPAQuery(query);
    }

    /**
     * INTERNAL:
     * Return all pre-defined not yet parsed EJBQL multitenant queries.
     */
    public void addJPATablePerTenantQuery(DatabaseQuery query) {
        getProject().addJPATablePerTenantQuery(query);
    }

    /**
     * PUBLIC:
     * Return a set of multitenant context properties this session
     */
    public void addMultitenantContextProperty(String contextProperty) {
        getMultitenantContextProperties().add(contextProperty);
    }

    /**
     * INTERNAL:
     * Add the query to the session queries.
     */
    protected synchronized void addQuery(DatabaseQuery query, boolean nameMustBeUnique) {
        Vector queriesByName = (Vector)getQueries().get(query.getName());
        if (queriesByName == null) {
            // lazily create Vector in Hashtable.
            queriesByName = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance();
            getQueries().put(query.getName(), queriesByName);
        }

        if (nameMustBeUnique){ // JPA addNamedQuery
            if (queriesByName.size() <= 1){
                queriesByName.clear();
            }else{
                throw new IllegalStateException(ExceptionLocalization.buildMessage("argument_keyed_named_query_with_JPA", new Object[]{query.getName()}));
            }
        }else{
            // Check that we do not already have a query that matched it
            for (Iterator enumtr = queriesByName.iterator(); enumtr.hasNext();) {
                DatabaseQuery existingQuery = (DatabaseQuery)enumtr.next();
                if (Helper.areTypesAssignable(query.getArgumentTypes(), existingQuery.getArgumentTypes())) {
                    throw ValidationException.existingQueryTypeConflict(query, existingQuery);
                }
            }
        }
        queriesByName.add(query);
    }

    /**
     * PUBLIC:
     * Add the query to the session queries with the given name.
     * This allows for common queries to be pre-defined, reused and executed by name.
     */
    @Override
    public void addQuery(String name, DatabaseQuery query) {
        query.setName(name);
        addQuery(query, false);
    }

    /**
     * PUBLIC:
     * Add the query to the session queries with the given name.
     * This allows for common queries to be pre-defined, reused and executed by name.
     */
    public void addQuery(String name, DatabaseQuery query, boolean replace) {
        query.setName(name);
        addQuery(query, replace);
    }

    /**
     * INTERNAL:
     * Add a metamodel class to model class reference.
     */
    public void addStaticMetamodelClass(String modelClassName, String metamodelClassName) {
        if (staticMetamodelClasses == null) {
            staticMetamodelClasses = new HashMap<>();
        }

        staticMetamodelClasses.put(modelClassName, metamodelClassName);
    }

    /**
     * INTERNAL:
     * Add a descriptor that is uses a table per tenant multitenant policy.
     */
    protected void addTablePerTenantDescriptor(ClassDescriptor descriptor) {
        getTablePerTenantDescriptors().add(descriptor);
    }

    /**
     * INTERNAL:
     * Add a query that queries a table per tenant entity
     */
    protected void addTablePerTenantQuery(DatabaseQuery query) {
        getTablePerTenantQueries().add(query);
    }

    /**
     * INTERNAL:
     * Called by beginTransaction() to start a transaction.
     * This starts a real database transaction.
     * Allows retry if the connection is dead.
     */
    protected void basicBeginTransaction() throws DatabaseException {
        Collection<Accessor> accessors = getAccessors();
        if (accessors == null) {
            return;
    }
        Accessor failedAccessor = null;
        try {
            for (Accessor accessor : accessors) {
                failedAccessor = accessor;
                basicBeginTransaction(accessor);
            }
        } catch (RuntimeException exception) {
            // If begin failed, rollback ones already started.
            for (Accessor accessor : accessors) {
                if (accessor == failedAccessor) {
                    break;
                }
                try {
                    accessor.rollbackTransaction(this);
                } catch (RuntimeException ignore) { }
            }
            throw exception;
        }
    }

    /**
     * INTERNAL:
     * Called by beginTransaction() to start a transaction.
     * This starts a real database transaction.
     * Allows retry if the connection is dead.
     */
    protected void basicBeginTransaction(Accessor accessor) throws DatabaseException {
        try {
            accessor.beginTransaction(this);
        } catch (DatabaseException databaseException) {
            // Retry if the failure was communication based?  (i.e. timeout, database down, can no longer ping)
            if ((!getDatasourceLogin().shouldUseExternalTransactionController()) && databaseException.isCommunicationFailure()) {
                DatabaseException exceptionToThrow = databaseException;
                Object[] args = new Object[1];
                args[0] = databaseException;
                log(SessionLog.INFO, SessionLog.TRANSACTION, "communication_failure_attempting_begintransaction_retry", args, null);
                // Attempt to reconnect connection.
                exceptionToThrow = retryTransaction(accessor, databaseException, 0, this);
                if (exceptionToThrow == null) {
                    // Retry was a success.
                    return;
                }
                handleException(exceptionToThrow);
            } else {
                handleException(databaseException);
            }
        } catch (RuntimeException exception) {
            handleException(exception);
        }
    }

    /**
     * INTERNAL:
     * A begin transaction failed.
     * Re-connect and retry the begin transaction.
     */
    public DatabaseException retryTransaction(Accessor accessor, DatabaseException databaseException, int retryCount, AbstractSession executionSession) {
        DatabaseException exceptionToThrow = databaseException;
        // Attempt to reconnect connection.
        int count = getLogin().getQueryRetryAttemptCount();
        while (retryCount < count) {
            try {
                // if database session then re-establish
                // connection
                // else the session will just get a new
                // connection from the pool
                accessor.reestablishConnection(this);
                accessor.beginTransaction(this);
                return null;
            } catch (DatabaseException newException) {
                // Need to use last exception, as may not be a communication exception.
                exceptionToThrow = newException;
                // failed to get connection because of
                // database error.
                ++retryCount;
                try {
                    // Give the failover time to recover.
                    Thread.sleep(getLogin().getDelayBetweenConnectionAttempts());
                    Object[] args = new Object[1];
                    args[0] = exceptionToThrow;
                    log(SessionLog.INFO, SessionLog.TRANSACTION, "communication_failure_attempting_begintransaction_retry", args, null);
                } catch (InterruptedException intEx) {
                    break;
                }
            }
        }
        return exceptionToThrow;
    }

    /**
     * INTERNAL:
     * Called in the end of beforeCompletion of external transaction synchronization listener.
     * Close the managed sql connection corresponding to the external transaction,
     * if applicable releases accessor.
     */
    public void releaseJTSConnection() {
    }

    /**
     * INTERNAL:
     * Called by commitTransaction() to commit a transaction.
     * This commits the active transaction.
     */
    protected void basicCommitTransaction() throws DatabaseException {
        Collection<Accessor> accessors = getAccessors();
        if (accessors == null) {
            return;
        }
        try {
            for (Accessor accessor : accessors) {
                accessor.commitTransaction(this);
            }
        } catch (RuntimeException exception) {
            // Leave transaction uncommitted as rollback should be called.
            handleException(exception);
        }
    }

    /**
     * INTERNAL:
     * Called by rollbackTransaction() to rollback a transaction.
     * This rolls back the active transaction.
     */
    protected void basicRollbackTransaction() throws DatabaseException {
        Collection<Accessor> accessors = getAccessors();
        if (accessors == null) {
            return;
        }
        RuntimeException exception = null;
        for (Accessor accessor : accessors) {
        try {
                accessor.rollbackTransaction(this);
            } catch (RuntimeException failure) {
                exception = failure;
            }
        }
        if (exception != null) {
            handleException(exception);
        }
    }

    /**
     * INTERNAL:
     * Attempts to begin an external transaction.
     * Returns true only in one case -
     * external transaction has been internally started during this method call:
     * wasJTSTransactionInternallyStarted()==false in the beginning of this method and
     * wasJTSTransactionInternallyStarted()==true in the end of this method.
     */
    public boolean beginExternalTransaction() {
        boolean externalTransactionHasBegun = false;
        if (hasExternalTransactionController() && !wasJTSTransactionInternallyStarted()) {
            try {
                getExternalTransactionController().beginTransaction(this);
            } catch (RuntimeException exception) {
                handleException(exception);
            }
            if (wasJTSTransactionInternallyStarted()) {
                externalTransactionHasBegun = true;
                log(SessionLog.FINER, SessionLog.TRANSACTION, "external_transaction_has_begun_internally");
            }
        }
        return externalTransactionHasBegun;
    }

    /**
     * PUBLIC:
     * Begin a transaction on the database.
     * This allows a group of database modification to be committed or rolled back as a unit.
     * All writes/deletes will be sent to the database be will not be visible to other users until commit.
     * Although databases do not allow nested transaction,
     * EclipseLink supports nesting through only committing to the database on the outer commit.
     *
     * @exception DatabaseException if the database connection is lost or the begin is rejected.
     * @exception ConcurrencyException if this session's transaction is acquired by another thread and a timeout occurs.
     *
     * @see #isInTransaction()
     */
    public void beginTransaction() throws DatabaseException, ConcurrencyException {
        ConcurrencyManager mutex = getTransactionMutex();
        // If there is no db transaction in progress
        // beginExternalTransaction() starts an external transaction -
        // provided externalTransactionController is used, and there is
        // no active external transaction - so we have to start one internally.
        if (!mutex.isAcquired()) {
            beginExternalTransaction();
        }
        // For unit of work and client session multi threading is allowed as they are a context,
        // this is required for JTS/RMI/CORBA/EJB stuff where the server thread can be different across calls.
        if (isClientSession()) {
            mutex.setActiveThread(Thread.currentThread());
        }

        // Ensure mutual exclusion and call subclass specific begin.
        mutex.acquire();
        if (!mutex.isNested()) {
            if (this.eventManager != null) {
                this.eventManager.preBeginTransaction();
            }
            basicBeginTransaction();
            if (this.eventManager != null) {
                this.eventManager.postBeginTransaction();
            }
        }
    }


    /**
     * Check to see if the descriptor of a superclass can be used to describe this class
     *
     * @return ClassDescriptor
     */
    protected ClassDescriptor checkHierarchyForDescriptor(Class theClass){
        return getDescriptor(theClass.getSuperclass());
    }

    /**
     * allow the entity listener injection manager to clean itself up.
     */
    public void cleanUpInjectionManager(){
        if (injectionManager != null){
            injectionManager.cleanUp(this);
        }
    }

    /**
     * PUBLIC:
     * clear the integrityChecker. IntegrityChecker holds all the ClassDescriptor Exceptions.
     */
    @Override
    public void clearIntegrityChecker() {
        setIntegrityChecker(null);
    }

    /**
     * INTERNAL:
     * Clear the the lastDescriptorAccessed cache.
     */
    public void clearLastDescriptorAccessed() {
        this.lastDescriptorAccessed = null;
    }

    /**
     * INTERNAL:
     * Clear the the descriptors cache.
     */
    public void clearDescriptors() {
        this.descriptors = null;
    }

    /**
     * PUBLIC:
     * Clear the profiler, this will end the current profile operation.
     */
    @Override
    public void clearProfile() {
        setProfiler(null);
    }

    /**
     * INTERNAL:
     * Clones the descriptor
     */
    @Override
    public Object clone() {
        // An alternative to this process should be found
        try {
            return super.clone();
        } catch (Exception exception) {
            throw new AssertionError(exception);
        }
    }

    /**
     * INTERNAL:
     * Attempts to commit the running internally started external transaction.
     * Returns true only in one case -
     * external transaction has been internally committed during this method call:
     * wasJTSTransactionInternallyStarted()==true in the beginning of this method and
     * wasJTSTransactionInternallyStarted()==false in the end of this method.
     */
    public boolean commitExternalTransaction() {
        boolean externalTransactionHasCommitted = false;
        if (hasExternalTransactionController() && wasJTSTransactionInternallyStarted()) {
            try {
                getExternalTransactionController().commitTransaction(this);
            } catch (RuntimeException exception) {
                handleException(exception);
            }
            if (!wasJTSTransactionInternallyStarted()) {
                externalTransactionHasCommitted = true;
                log(SessionLog.FINER, SessionLog.TRANSACTION, "external_transaction_has_committed_internally");
            }
        }
        return externalTransactionHasCommitted;
    }

    /**
     * PUBLIC:
     * Commit the active database transaction.
     * This allows a group of database modification to be committed or rolled back as a unit.
     * All writes/deletes will be sent to the database be will not be visible to other users until commit.
     * Although databases do not allow nested transaction,
     * EclipseLink supports nesting through only committing to the database on the outer commit.
     *
     * @exception DatabaseException most databases validate changes as they are done,
     * normally errors do not occur on commit unless the disk fails or the connection is lost.
     * @exception ConcurrencyException if this session is not within a transaction.
     */
    public void commitTransaction() throws DatabaseException, ConcurrencyException {
        ConcurrencyManager mutex = getTransactionMutex();
        // Release mutex and call subclass specific commit.
        if (!mutex.isNested()) {
            if (this.eventManager != null) {
                this.eventManager.preCommitTransaction();
            }
            basicCommitTransaction();
            if (this.eventManager != null) {
                this.eventManager.postCommitTransaction();
            }
        }

        // This MUST not be in a try catch or finally as if the commit failed the transaction is still open.
        mutex.release();

        // If there is no db transaction in progress
        // if there is an active external transaction
        // which was started internally - it should be committed internally, too.
        if (!mutex.isAcquired()) {
            commitExternalTransaction();
        }
    }

    /**
     * INTERNAL:
     * Return if the two object match completely.
     * This checks the objects attributes and their private parts.
     */
    public boolean compareObjects(Object firstObject, Object secondObject) {
        if ((firstObject == null) && (secondObject == null)) {
            return true;
        }

        if ((firstObject == null) || (secondObject == null)) {
            return false;
        }

        if (!(firstObject.getClass().equals(secondObject.getClass()))) {
            return false;
        }

        ObjectBuilder builder = getDescriptor(firstObject.getClass()).getObjectBuilder();

        return builder.compareObjects(builder.unwrapObject(firstObject, this), builder.unwrapObject(secondObject, this), this);
    }

    /**
     * TESTING:
     * Return true if the object do not match.
     * This checks the objects attributes and their private parts.
     */
    public boolean compareObjectsDontMatch(Object firstObject, Object secondObject) {
        return !this.compareObjects(firstObject, secondObject);
    }

    /**
     * PUBLIC:
     * Return true if the pre-defined query is defined on the session.
     */
    @Override
    public boolean containsQuery(String queryName) {
        return getQueries().containsKey(queryName);
    }

    /**
     * PUBLIC:
     * Return a complete copy of the object or of collection of objects.
     * In case of collection all members should be either entities of the same type
     * or have a common inheritance hierarchy mapped root class.
     * This can be used to obtain a scratch copy of an object,
     * or for templatizing an existing object into another new object.
     * The object and all of its privately owned parts will be copied.
     *
     * @see #copy(Object, AttributeGroup)
     */
    @Override
    public Object copy(Object originalObjectOrObjects) {
        return copy(originalObjectOrObjects, new CopyGroup());
    }

    /**
     * PUBLIC:
     * Return a complete copy of the object or of collection of objects.
     * In case of collection all members should be either entities of the same type
     * or have a common inheritance hierarchy mapped root class.
     * This can be used to obtain a scratch copy of an object,
     * or for templatizing an existing object into another new object.
     * If there are no attributes in the group
     * then the object and all of its privately owned parts will be copied.
     * Otherwise only the attributes included into the group will be copied.
     */
    @Override
    public Object copy(Object originalObjectOrObjects, AttributeGroup group) {
        if (originalObjectOrObjects == null) {
            return null;
        }

        CopyGroup copyGroup = group.toCopyGroup();
        copyGroup.setSession(this);
        if(originalObjectOrObjects instanceof Collection) {
            // it's a collection - make sure all elements use the same instance of CopyGroup.
            Collection originalCollection = (Collection)originalObjectOrObjects;
            Collection copies;
            if(originalCollection instanceof List) {
                copies = new ArrayList();
            } else {
                copies = new HashSet();
            }
            Iterator it = originalCollection.iterator();
            while(it.hasNext()) {
                copies.add(copyInternal(it.next(), copyGroup));
            }
            return copies;
        }

        // it's not a collection
        return copyInternal(originalObjectOrObjects, copyGroup);
    }

    /**
     * INTERNAL:
     */
    public Object copyInternal(Object originalObject, CopyGroup copyGroup) {
        if (originalObject == null) {
            return null;
        }

        ClassDescriptor descriptor = getDescriptor(originalObject);
        if (descriptor == null) {
            return originalObject;
        }

        return descriptor.getObjectBuilder().copyObject(originalObject, copyGroup);
    }

    /**
     * INTERNAL:
     * Copy the read only classes from the unit of work
     *
     * Added Nov 8, 2000 JED for Patch 2.5.1.8
     * Ref: Prs 24502
     */
    public Vector copyReadOnlyClasses() {
        return getDefaultReadOnlyClasses();
    }

    public DatabaseValueHolder createCloneQueryValueHolder(ValueHolderInterface attributeValue, Object clone, AbstractRecord row, ForeignReferenceMapping mapping) {
        return new ProtectedValueHolder(attributeValue, mapping, this);
    }

    public DatabaseValueHolder createCloneTransformationValueHolder(ValueHolderInterface attributeValue, Object original, Object clone, AbstractTransformationMapping mapping) {
        return new ProtectedValueHolder(attributeValue, mapping, this);
    }

    public <T> InjectionManager<T> createInjectionManager(Object beanManager){
        try{
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    Class elim = AccessController.doPrivileged(new PrivilegedClassForName(InjectionManager.DEFAULT_CDI_INJECTION_MANAGER, true, getLoader()));
                    Constructor constructor = AccessController.doPrivileged(new PrivilegedGetConstructorFor(elim, new Class[] {String.class}, false));
                    return (InjectionManager<T>) AccessController.doPrivileged(new PrivilegedInvokeConstructor(constructor, new Object[] {beanManager}));
            } else {
                Class elim = org.eclipse.persistence.internal.security.PrivilegedAccessHelper.getClassForName(InjectionManager.DEFAULT_CDI_INJECTION_MANAGER, true, getLoader());
                Constructor constructor = PrivilegedAccessHelper.getConstructorFor(elim, new Class[] {Object.class}, false);
                return (InjectionManager<T>) PrivilegedAccessHelper.invokeConstructor(constructor, new Object[] {beanManager});
            }
        } catch (Exception e){
            logThrowable(SessionLog.FINEST, SessionLog.JPA, e);
        }
        return new DisabledInjectionManager<>();
    }

    /**
     * INTERNAL:
     * This method is similar to getAndCloneCacheKeyFromParent.  It purpose is to get protected cache data from the shared cache and
     * build/return a protected instance.
     */
    public Object createProtectedInstanceFromCachedData(Object cached, Integer refreshCascade, ClassDescriptor descriptor){
        CacheKey localCacheKey = getIdentityMapAccessorInstance().getCacheKeyForObject(cached);
        if (localCacheKey != null && localCacheKey.getObject() != null){
            return localCacheKey.getObject();
        }
        boolean identityMapLocked = this.shouldCheckWriteLock && getParent().getIdentityMapAccessorInstance().acquireWriteLock();
        boolean rootOfCloneRecursion = false;
        CacheKey cacheKey = getParent().getIdentityMapAccessorInstance().getCacheKeyForObject(cached);
        try{
            Object key = null;
            Object lockValue = null;
            long readTime = 0;
            if (cacheKey != null){
                if (identityMapLocked) {
                    checkAndRefreshInvalidObject(cached, cacheKey, descriptor);
                } else {
                    // Check if we have locked all required objects already.
                    if (this.objectsLockedForClone == null) {
                        // PERF: If a simple object just acquire a simple read-lock.
                        if (descriptor.shouldAcquireCascadedLocks()) {
                            this.objectsLockedForClone = getParent().getIdentityMapAccessorInstance().getWriteLockManager().acquireLocksForClone(cached, descriptor, cacheKey, this);
                        } else {
                            checkAndRefreshInvalidObject(cached, cacheKey, descriptor);
                            cacheKey.acquireReadLock();
                        }
                        rootOfCloneRecursion = true;
                    }
                }
                key = cacheKey.getKey();
                lockValue = cacheKey.getWriteLockValue();
                readTime = cacheKey.getReadTime();
            }
            if (descriptor.hasInheritance()){
                descriptor = this.getClassDescriptor(cached.getClass());
            }
            ObjectBuilder builder = descriptor.getObjectBuilder();
            Object workingClone = builder.instantiateWorkingCopyClone(cached, this);
            // PERF: Cache the primary key if implements PersistenceEntity.
            builder.populateAttributesForClone(cached, cacheKey,  workingClone, refreshCascade, this);
            getIdentityMapAccessorInstance().putInIdentityMap(workingClone, key, lockValue, readTime, descriptor);
            return workingClone;
        }finally{
            if (rootOfCloneRecursion){
                if (this.objectsLockedForClone == null && cacheKey != null) {
                    cacheKey.releaseReadLock();
                } else {
                    for (Iterator iterator = this.objectsLockedForClone.values().iterator(); iterator.hasNext();) {
                        ((CacheKey)iterator.next()).releaseReadLock();
                    }
                    this.objectsLockedForClone = null;
                }
                executeDeferredEvents();
            }
        }
    }

        /**
         * INTERNAL:
         * Check if the object is invalid and refresh it.
         * This is used to ensure that no invalid objects are registered.
         */
        public void checkAndRefreshInvalidObject(Object object, CacheKey cacheKey, ClassDescriptor descriptor) {
            if (isConsideredInvalid(object, cacheKey, descriptor)) {
                ReadObjectQuery query = new ReadObjectQuery();
                query.setReferenceClass(object.getClass());
                query.setSelectionId(cacheKey.getKey());
                query.refreshIdentityMapResult();
                query.setIsExecutionClone(true);
                this.executeQuery(query);
            }
        }

        /**
         * INTERNAL:
         * Check if the object is invalid and *should* be refreshed.
         * This is used to ensure that no invalid objects are cloned.
         */
        public boolean isConsideredInvalid(Object object, CacheKey cacheKey, ClassDescriptor descriptor) {
            if (cacheKey.getObject() != null) {
                CacheInvalidationPolicy cachePolicy = descriptor.getCacheInvalidationPolicy();
                // BUG#6671556 refresh invalid objects when accessed in the unit of work.
                return (cachePolicy.shouldRefreshInvalidObjectsOnClone() && cachePolicy.isInvalidated(cacheKey));
            }
            return false;
        }

    /**
     * INTERNAL:
     * Add an event to the deferred list.  Events will be fired after the operation completes
     */
    public void deferEvent(DescriptorEvent event){
        if (this.deferredEvents == null){
            this.deferredEvents = new ArrayList<>();
        }
        this.deferredEvents.add(event);
    }

    /**
     * PUBLIC:
     * delete all of the objects and all of their privately owned parts in the database.
     * The allows for a group of objects to be deleted as a unit.
     * The objects will be deleted through a single transactions.
     *
     * @exception DatabaseException if an error occurs on the database,
     * these include constraint violations, security violations and general database errors.
     * @exception OptimisticLockException if the object's descriptor is using optimistic locking and
     * the object has been updated or deleted by another user since it was last read.
     */
    public void deleteAllObjects(Collection domainObjects) throws DatabaseException, OptimisticLockException {
        for (Iterator objectsEnum = domainObjects.iterator(); objectsEnum.hasNext();) {
            deleteObject(objectsEnum.next());
        }
    }

    /**
     * PUBLIC:
     * Delete the object and all of its privately owned parts from the database.
     * The delete operation can be customized through using a delete query.
     *
     * @exception DatabaseException if an error occurs on the database,
     * these include constraint violations, security violations and general database errors.
     * An database error is not raised if the object is already deleted or no rows are effected.
     * @exception OptimisticLockException if the object's descriptor is using optimistic locking and
     * the object has been updated or deleted by another user since it was last read.
     *
     * @see DeleteObjectQuery
     */
    public Object deleteObject(Object domainObject) throws DatabaseException, OptimisticLockException {
        DeleteObjectQuery query = new DeleteObjectQuery();
        query.setObject(domainObject);
        query.setIsExecutionClone(true);
        return executeQuery(query);
    }

    /**
     * PUBLIC:
     * Return if the object exists on the database or not.
     * This always checks existence on the database.
     */
    @Override
    public boolean doesObjectExist(Object object) throws DatabaseException {
        DoesExistQuery query = new DoesExistQuery();
        query.setObject(object);
        query.checkDatabaseForDoesExist();
        query.setIsExecutionClone(true);
        return (Boolean) executeQuery(query);
    }

    /**
     * PUBLIC:
     * Turn off logging
     */
    @Override
    public void dontLogMessages() {
        setLogLevel(SessionLog.OFF);
    }

    /**
     * INTERNAL:
     * End the operation timing.
     */
    @Override
    public void endOperationProfile(String operationName) {
        if (this.isInProfile) {
            getProfiler().endOperationProfile(operationName);
        }
    }

    /**
     * INTERNAL:
     * End the operation timing.
     */
    public void endOperationProfile(String operationName, DatabaseQuery query, int weight) {
        if (this.isInProfile) {
            getProfiler().endOperationProfile(operationName, query, weight);
        }
    }

    /**
     * INTERNAL:
     * Updates the value of SessionProfiler state
     */
    @Override
    public void updateProfile(String operationName, Object value) {
        if (this.isInProfile) {
            getProfiler().update(operationName, value);
        }
    }

    /**
     * INTERNAL:
     * Set the table per tenant. This should be called per client session after
     * the start of a transaction. From JPA this method is called on the entity
     * manager by setting the multitenant table per tenant property.
     */
    public void updateTablePerTenantDescriptors(String property, Object value) {
        // When all the table per tenant descriptors are set, we should initialize them.
        boolean shouldInitializeDescriptors = hasTablePerTenantDescriptors();

        for (ClassDescriptor descriptor : getTablePerTenantDescriptors()) {
            TablePerMultitenantPolicy policy = (TablePerMultitenantPolicy) descriptor.getMultitenantPolicy();

            if ((! policy.hasContextTenant()) && policy.usesContextProperty(property)) {
                policy.setContextTenant((String) value);
            }

            shouldInitializeDescriptors = shouldInitializeDescriptors && policy.hasContextTenant();
        }

        if (shouldInitializeDescriptors) {
            // Now that the correct tables are set on all table per tenant
            // descriptors, we can go through the initialization phases safely.
            try {
                // First initialize basic properties (things that do not depend on anything else)
                for (ClassDescriptor descriptor : tablePerTenantDescriptors) {
                    descriptor.preInitialize(this);
                }

                // Second initialize basic mappings
                for (ClassDescriptor descriptor : tablePerTenantDescriptors) {
                    descriptor.initialize(this);
                }

                // Third initialize child dependencies
                for (ClassDescriptor descriptor : tablePerTenantDescriptors) {
                    descriptor.postInitialize(this);
                }

                if (getIntegrityChecker().hasErrors()) {
                    handleSevere(new IntegrityException(getIntegrityChecker()));
                }
            } finally {
                clearIntegrityChecker();
            }

            getCommitManager().initializeCommitOrder();

            // If we have table per tenant queries, initialize and add them now
            // once all the descriptors have been initialized.
            if (hasTablePerTenantQueries()) {
                for (DatabaseQuery query : getTablePerTenantQueries()) {
                    processJPAQuery(query);
                }
            }
        }
    }

    /**
     * INTERNAL:
     * Updates the count of SessionProfiler event
     */
    @Override
    public void incrementProfile(String operationName) {
        if (this.isInProfile) {
            getProfiler().occurred(operationName, this);
        }
    }

    /**
     * INTERNAL:
     * Updates the count of SessionProfiler event
     */
    public void incrementProfile(String operationName, DatabaseQuery query) {
        if (this.isInProfile) {
            getProfiler().occurred(operationName, query, this);
        }
    }

    /**
     * INTERNAL:
     * Causes any deferred events to be fired.  Called after operation completes
     */
    public void executeDeferredEvents(){
        if (!this.isExecutingEvents && this.deferredEvents != null) {
            this.isExecutingEvents = true;
            try {
                for (int i = 0; i < this.deferredEvents.size(); ++i) {
                    // the size is checked every time here because the list may grow
                    DescriptorEvent event = this.deferredEvents.get(i);
                    event.getDescriptor().getEventManager().executeEvent(event);
                }
                this.deferredEvents.clear();
            } finally {
                this.isExecutingEvents = false;
            }
        }
    }


    /**
     * INTERNAL:
     * Overridden by subclasses that do more than just execute the call.
     * Executes the call directly on this session and does not check which
     * session it should have executed on.
     */
    public Object executeCall(Call call, AbstractRecord translationRow, DatabaseQuery query) throws DatabaseException {
        if (query.getAccessors() == null) {
            query.setAccessors(getAccessors());
        }
        try {
            return basicExecuteCall(call, translationRow, query);
        } finally {
            if (call.isFinished()) {
                query.setAccessors(null);
            }
        }
    }

    /**
     * INTERNAL:
     * Release (if required) connection after call.
     */
    public void releaseConnectionAfterCall(DatabaseQuery query) {
    }

    /**
     * PUBLIC:
     * Execute the call on the database.
     * The row count is returned.
     * The call can be a stored procedure call, SQL call or other type of call.
     * <p>Example:
     * <p>session.executeNonSelectingCall(new SQLCall("Delete from Employee");
     *
     * @see #executeSelectingCall(Call)
     */
    @Override
    public int executeNonSelectingCall(Call call) throws DatabaseException {
        DataModifyQuery query = new DataModifyQuery();
        query.setIsExecutionClone(true);
        query.setCall(call);
        Integer value = (Integer)executeQuery(query);
        if (value == null) {
            return 0;
        } else {
            return value;
        }
    }

    /**
     * PUBLIC:
     * Execute the sql on the database.
     * <p>Example:
     * <p>session.executeNonSelectingSQL("Delete from Employee");
     * @see #executeNonSelectingCall(Call)
     * Warning: Allowing an unverified SQL string to be passed into this
     * method makes your application vulnerable to SQL injection attacks.
     */
    @Override
    public void executeNonSelectingSQL(String sqlString) throws DatabaseException {
        executeNonSelectingCall(new SQLCall(sqlString));
    }

    /**
     * PUBLIC:
     * Execute the pre-defined query by name and return the result.
     * Queries can be pre-defined and named to allow for their reuse.
     *
     * @see #addQuery(String, DatabaseQuery)
     */
    @Override
    public Object executeQuery(String queryName) throws DatabaseException {
        DatabaseQuery query = getQuery(queryName);

        if (query == null) {
            throw QueryException.queryNotDefined(queryName);
        }

        return executeQuery(query);
    }

    /**
     * PUBLIC:
     * Execute the pre-defined query by name and return the result.
     * Queries can be pre-defined and named to allow for their reuse.
     * The class is the descriptor in which the query was pre-defined.
     *
     * @see DescriptorQueryManager#addQuery(String, DatabaseQuery)
     */
    @Override
    public Object executeQuery(String queryName, Class domainClass) throws DatabaseException {
        ClassDescriptor descriptor = getDescriptor(domainClass);

        if (descriptor == null) {
            throw QueryException.descriptorIsMissingForNamedQuery(domainClass, queryName);
        }

        DatabaseQuery query = descriptor.getQueryManager().getQuery(queryName);

        if (query == null) {
            throw QueryException.queryNotDefined(queryName, domainClass);
        }

        return executeQuery(query);
    }

    /**
     * PUBLIC:
     * Execute the pre-defined query by name and return the result.
     * Queries can be pre-defined and named to allow for their reuse.
     * The class is the descriptor in which the query was pre-defined.
     *
     * @see DescriptorQueryManager#addQuery(String, DatabaseQuery)
     */
    @Override
    public Object executeQuery(String queryName, Class domainClass, Object arg1) throws DatabaseException {
        Vector argumentValues = new Vector();
        argumentValues.addElement(arg1);
        return executeQuery(queryName, domainClass, argumentValues);
    }

    /**
     * PUBLIC:
     * Execute the pre-defined query by name and return the result.
     * Queries can be pre-defined and named to allow for their reuse.
     * The class is the descriptor in which the query was pre-defined.
     *
     * @see DescriptorQueryManager#addQuery(String, DatabaseQuery)
     */
    @Override
    public Object executeQuery(String queryName, Class domainClass, Object arg1, Object arg2) throws DatabaseException {
        Vector argumentValues = new Vector();
        argumentValues.addElement(arg1);
        argumentValues.addElement(arg2);
        return executeQuery(queryName, domainClass, argumentValues);
    }

    /**
     * PUBLIC:
     * Execute the pre-defined query by name and return the result.
     * Queries can be pre-defined and named to allow for their reuse.
     * The class is the descriptor in which the query was pre-defined.
     *
     * @see DescriptorQueryManager#addQuery(String, DatabaseQuery)
     */
    @Override
    public Object executeQuery(String queryName, Class domainClass, Object arg1, Object arg2, Object arg3) throws DatabaseException {
        Vector argumentValues = new Vector();
        argumentValues.addElement(arg1);
        argumentValues.addElement(arg2);
        argumentValues.addElement(arg3);
        return executeQuery(queryName, domainClass, argumentValues);
    }

    /**
     * PUBLIC:
     * Execute the pre-defined query by name and return the result.
     * Queries can be pre-defined and named to allow for their reuse.
     * The class is the descriptor in which the query was pre-defined.
     *
     * @see DescriptorQueryManager#addQuery(String, DatabaseQuery)
     */
    @Override
    public Object executeQuery(String queryName, Class domainClass, List argumentValues) throws DatabaseException {
        if (argumentValues instanceof Vector) {
            return executeQuery(queryName, domainClass, (Vector)argumentValues);
        } else {
            return executeQuery(queryName, domainClass, new Vector(argumentValues));
        }
    }

    /**
     * PUBLIC:
     * Execute the pre-defined query by name and return the result.
     * Queries can be pre-defined and named to allow for their reuse.
     * The class is the descriptor in which the query was pre-defined.
     *
     * @see DescriptorQueryManager#addQuery(String, DatabaseQuery)
     */
    public Object executeQuery(String queryName, Class domainClass, Vector argumentValues) throws DatabaseException {
        ClassDescriptor descriptor = getDescriptor(domainClass);

        if (descriptor == null) {
            throw QueryException.descriptorIsMissingForNamedQuery(domainClass, queryName);
        }

        DatabaseQuery query = descriptor.getQueryManager().getQuery(queryName, argumentValues);

        if (query == null) {
            throw QueryException.queryNotDefined(queryName, domainClass);
        }

        return executeQuery(query, argumentValues);
    }

    /**
     * PUBLIC:
     * Execute the pre-defined query by name and return the result.
     * Queries can be pre-defined and named to allow for their reuse.
     *
     * @see #addQuery(String, DatabaseQuery)
     */
    @Override
    public Object executeQuery(String queryName, Object arg1) throws DatabaseException {
        Vector argumentValues = new Vector();
        argumentValues.addElement(arg1);
        return executeQuery(queryName, argumentValues);
    }

    /**
     * PUBLIC:
     * Execute the pre-defined query by name and return the result.
     * Queries can be pre-defined and named to allow for their reuse.
     *
     * @see #addQuery(String, DatabaseQuery)
     */
    @Override
    public Object executeQuery(String queryName, Object arg1, Object arg2) throws DatabaseException {
        Vector argumentValues = new Vector();
        argumentValues.addElement(arg1);
        argumentValues.addElement(arg2);
        return executeQuery(queryName, argumentValues);
    }

    /**
     * PUBLIC:
     * Execute the pre-defined query by name and return the result.
     * Queries can be pre-defined and named to allow for their reuse.
     *
     * @see #addQuery(String, DatabaseQuery)
     */
    @Override
    public Object executeQuery(String queryName, Object arg1, Object arg2, Object arg3) throws DatabaseException {
        Vector argumentValues = new Vector();
        argumentValues.addElement(arg1);
        argumentValues.addElement(arg2);
        argumentValues.addElement(arg3);
        return executeQuery(queryName, argumentValues);
    }

    /**
     * PUBLIC:
     * Execute the pre-defined query by name and return the result.
     * Queries can be pre-defined and named to allow for their reuse.
     *
     * @see #addQuery(String, DatabaseQuery)
     */
    @Override
    public Object executeQuery(String queryName, List argumentValues) throws DatabaseException {
        if (argumentValues instanceof Vector) {
            return executeQuery(queryName, (Vector)argumentValues);
        } else {
            return executeQuery(queryName, new Vector(argumentValues));
        }
    }

    /**
     * PUBLIC:
     * Execute the pre-defined query by name and return the result.
     * Queries can be pre-defined and named to allow for their reuse.
     *
     * @see #addQuery(String, DatabaseQuery)
     */
    public Object executeQuery(String queryName, Vector argumentValues) throws DatabaseException {
        DatabaseQuery query = getQuery(queryName, argumentValues);

        if (query == null) {
            throw QueryException.queryNotDefined(queryName);
        }

        return executeQuery(query, argumentValues);
    }

    /**
     * PUBLIC:
     * Execute the database query.
     * A query is a database operation such as reading or writing.
     * The query allows for the operation to be customized for such things as,
     * performance, depth, caching, etc.
     *
     * @see DatabaseQuery
     */
    @Override
    public Object executeQuery(DatabaseQuery query) throws DatabaseException {
        return executeQuery(query, EmptyRecord.getEmptyRecord());
    }

    /**
     * PUBLIC:
     * Return the results from executing the database query.
     * The query arguments are passed in as a List of argument values in the same order as the query arguments.
     */
    @Override
    public Object executeQuery(DatabaseQuery query, List argumentValues) throws DatabaseException {
        if (query == null) {
            throw QueryException.queryNotDefined();
        }
        AbstractRecord row = query.rowFromArguments(argumentValues, this);

        return executeQuery(query, row);
    }

    /**
     * INTERNAL:
     * Return the results from executing the database query.
     * the arguments should be a database row with raw data values.
     */
    public Object executeQuery(DatabaseQuery query, AbstractRecord row) throws DatabaseException {
        if (hasBroker()) {
            if (!((query.isDataModifyQuery() || query.isDataReadQuery()) && (query.getSessionName() == null))) {
                return getBroker().executeQuery(query, row);
            }
        }

        if (query == null) {
            throw QueryException.queryNotDefined();
        }

        // Check for disabled native queries.
        if (query.isUserDefinedSQLCall() && query.isSQLCallQuery() && ! query.isJPQLCallQuery()) {
            if (! query.shouldAllowNativeSQLQuery(getProject().allowNativeSQLQueries())) {
                // If the session/project says no to SQL queries and the database
                // query doesn't ask to bypass this decision then throw an exception.
                throw QueryException.nativeSQLQueriesAreDisabled(query);
            }
        }

        //CR#2272
        log(SessionLog.FINEST, SessionLog.QUERY, "execute_query", query);

        //Make a call to the internal method with a retry count of 0.  This will
        //initiate a retry call stack if required and supported.  The separation between the
        //calling stack and the target method is made because the target method may call itself
        //recursively.
        return this.executeQuery(query, row, 0);
    }

    /**
     * INTERNAL:
     * Return the results from executing the database query.
     * the arguments should be a database row with raw data values.
     */
    public Object executeQuery(DatabaseQuery query, AbstractRecord row, int retryCount) throws DatabaseException {

        try {
            if (this.eventManager != null) {
                this.eventManager.preExecuteQuery(query);
            }
            Object result;
            if (isInProfile()) {
                result = getProfiler().profileExecutionOfQuery(query, row, this);
            } else {
                result = internalExecuteQuery(query, row);
            }
            if (this.eventManager != null) {
                this.eventManager.postExecuteQuery(query, result);
            }
            return result;
        } catch (RuntimeException exception) {
            if (exception instanceof QueryException) {
                QueryException queryException = (QueryException)exception;
                if (queryException.getQuery() == null) {
                    queryException.setQuery(query);
                }
                if (queryException.getQueryArgumentsRecord() == null) {
                    queryException.setQueryArguments(row);
                }
                if (queryException.getSession() == null) {
                    queryException.setSession(this);
                }
            } else if (exception instanceof DatabaseException) {
                DatabaseException databaseException = (DatabaseException)exception;
                if (databaseException.getQuery() == null) {
                    databaseException.setQuery(query);
                }
                if (databaseException.getQueryArgumentsRecord() == null) {
                    databaseException.setQueryArguments(row);
                }
                if (databaseException.getSession() == null) {
                    databaseException.setSession(this);
                }
                //if this query is a read query outside of a transaction then we may be able to retry the query
                if (!isInTransaction() && query.isReadQuery() && getDatasourceLogin() instanceof DatabaseLogin) {
                    final int count = getLogin().getQueryRetryAttemptCount();
                    //was the failure communication based?  (ie timeout)
                    if (databaseException.isCommunicationFailure() && retryCount < count) {
                        Object[] args = new Object[1];
                        args[0] = databaseException;
                        log(SessionLog.INFO, SessionLog.QUERY, "communication_failure_attempting_query_retry", args, null);
                        Object result = retryQuery(query, row, databaseException, retryCount, this);
                        if (result instanceof DatabaseException) {
                            exception = (DatabaseException)result;
                        } else {
                            return result;
                        }
                    }
                }
            }
            return handleException(exception);
        }
    }

    /**
     * INTERNAL:
     * A query execution failed due to an invalid query.
     * Re-connect and retry the query.
     */
    public Object retryQuery(DatabaseQuery query, AbstractRecord row, DatabaseException databaseException, int retryCount, AbstractSession executionSession) {
        DatabaseException exception = databaseException;
        //retry
        if (retryCount <= getLogin().getQueryRetryAttemptCount()) {
            try {
                // attempt to reconnect for a certain number of times.
                // servers may take some time to recover.
                ++retryCount;
                try {
                    //passing the retry count will prevent a runaway retry where
                    // we can acquire connections but are unable to execute any queries
                    if (retryCount > 1) {
                        // We are retrying more than once lets wait to give connection time to restart.
                        //Give the failover time to recover.
                        Thread.sleep(getLogin().getDelayBetweenConnectionAttempts());
                    }
                    return executionSession.executeQuery(query, row, retryCount);
                } catch (DatabaseException newException){
                    //replace original exception with last exception thrown
                    //this exception could be a data based exception as opposed
                    //to a connection exception that needs to go back to the customer.
                    exception = newException;
                }
            } catch (InterruptedException ex) {
                //Ignore interrupted exception.
            }
        }
        return exception;
    }

    /**
     * PUBLIC:
     * Execute the call on the database and return the result.
     * The call must return a value, if no value is return executeNonSelectCall must be used.
     * The call can be a stored procedure call, SQL call or other type of call.
     * A vector of database rows is returned, database row implements Java 2 Map which should be used to access the data.
     * <p>Example:
     * <p>session.executeSelectingCall(new SQLCall("Select * from Employee");
     *
     * @see #executeNonSelectingCall(Call)
     */
    @Override
    public Vector executeSelectingCall(Call call) throws DatabaseException {
        DataReadQuery query = new DataReadQuery();
        query.setCall(call);
        query.setIsExecutionClone(true);
        return (Vector)executeQuery(query);
    }

    /**
     * PUBLIC:
     * Execute the sql on the database and return the result.
     * It must return a value, if no value is return executeNonSelectingSQL must be used.
     * A vector of database rows is returned, database row implements Java 2 Map which should be used to access the data.
      * Warning: Allowing an unverified SQL string to be passed into this
     * method makes your application vulnerable to SQL injection attacks.
     * <p>Example:
     * <p>session.executeSelectingCall("Select * from Employee");
     *
     * @see #executeSelectingCall(Call)
     */
    @Override
    public Vector executeSQL(String sqlString) throws DatabaseException {
        return executeSelectingCall(new SQLCall(sqlString));
    }

    /**
     * INTERNAL:
     * This should normally not be used, most sessions do not have a single accessor.
     * ServerSession has a set of connection pools.
     * ClientSession only has an accessor during a transaction.
     * SessionBroker has multiple accessors.
     * getAccessors() should be used to support partitioning.
     * To maintain backward compatibility, and to support certain cases that required a default accessor,
     * this returns the first accessor.
     */
    public Accessor getAccessor() {
        Collection<Accessor> accessors = getAccessors();
        if ((accessors == null) || accessors.isEmpty()) {
            return null;
        }
        if (accessors instanceof List) {
            return ((List<Accessor>)accessors).get(0);
        }
        return accessors.iterator().next();
    }

    /**
     * INTERNAL:
     * This should normally not be used, most sessions do not have specific accessors.
     * ServerSession has a set of connection pools.
     * ClientSession only has an accessor during a transaction.
     * SessionBroker has multiple accessors.
     * getAccessors() is used to support partitioning.
     * If the accessor is null, this lazy initializes one for backwardcompatibility with DatabaseSession.
     */
    public Collection<Accessor> getAccessors() {
        if ((this.accessors == null) && (this.project != null) && (this.project.getDatasourceLogin() != null)) {
            synchronized (this) {
                if ((this.accessors == null) && (this.project != null) && (this.project.getDatasourceLogin() != null)) {
                    // PERF: lazy init, not always required.
                    List<Accessor> newAccessors = new ArrayList(1);
                    newAccessors.add(this.project.getDatasourceLogin().buildAccessor());
                    this.accessors = newAccessors;
                }
            }
        }
        return this.accessors;
    }

    /**
     * INTERNAL:
     * Return the connections to use for the query execution.
     */
    public Collection<Accessor> getAccessors(Call call, AbstractRecord translationRow, DatabaseQuery query) {
        // Check for partitioning.
        Collection<Accessor> accessors = null;
        if (query.getPartitioningPolicy() != null) {
            accessors = query.getPartitioningPolicy().getConnectionsForQuery(this, query, translationRow);
            if (accessors != null) {
                return accessors;
            }
        }
        ClassDescriptor descriptor = query.getDescriptor();
        if ((descriptor != null) && (descriptor.getPartitioningPolicy() != null)) {
            accessors = descriptor.getPartitioningPolicy().getConnectionsForQuery(this, query, translationRow);
            if (accessors != null) {
                return accessors;
            }
        }
        if (this.partitioningPolicy != null) {
            accessors = this.partitioningPolicy.getConnectionsForQuery(this, query, translationRow);
            if (accessors != null) {
                return accessors;
            }
        }
        return accessors;
    }

    /**
     * INTERNAL:
     * Execute the call on each accessors and merge the results.
     */
    public Object basicExecuteCall(Call call, AbstractRecord translationRow, DatabaseQuery query) throws DatabaseException {
        Object result = null;

        if (this.eventManager != null) {
            this.eventManager.preExecuteCall(call);
        }

        try {
            if (query.getAccessors().size() == 1) {
                result = query.getAccessor().executeCall(call, translationRow, this);
            } else {
                RuntimeException exception = null;
                // Replication or partitioning may require execution on multiple connections.
                for (Accessor accessor : query.getAccessors()) {
                    Object object = null;
                    try {
                        object = accessor.executeCall(call, translationRow, this);
                    } catch (RuntimeException failed) {
                        // Catch any exceptions to allow execution on each connections.
                        // This is used to have DDL run on every database even if one db fails because table already exists.
                        if (exception == null) {
                            exception = failed;
                        }
                    }
                    if (call.isOneRowReturned()) {
                        // If one row is desired, then break on first hit.
                        if (object != null) {
                            result = object;
                            break;
                        }
                    } else if (call.isNothingReturned()) {
                        // If no return ensure row count is consistent, 0 if any 0, otherwise first number.
                        if (result == null) {
                            result = object;
                        } else {
                            if (object instanceof Integer) {
                                if ((Integer) result != 0) {
                                    if ((Integer) object != 0) {
                                        result = object;
                                    }
                                }
                            }
                        }
                    } else {
                        // Either a set of rows (union), or cursor (return).
                        if (result == null) {
                            result = object;
                        } else {
                            if (object instanceof List) {
                                ((List)result).addAll((List)object);
                            } else {
                                break; // Not sure what to do, so break (if a cursor, don't only want to open one cursor.
                            }
                        }
                    }
                }
                if (exception != null) {
                    throw exception;
                }
            }
        } finally {
            if (this.eventManager != null) {
                this.eventManager.postExecuteCall(call, result);
            }
        }
        return result;
    }

    /**
     * INTERNAL:
     */
    public ExposedNodeLinkedList getActiveCommandThreads() {
        if (activeCommandThreads == null) {
            activeCommandThreads = new ExposedNodeLinkedList();
        }

        return activeCommandThreads;
    }

    /**
     * PUBLIC:
     * Return the active session for the current active external (JTS) transaction.
     * This should only be used with JTS and will return the session if no external transaction exists.
     */
    @Override
    public org.eclipse.persistence.sessions.Session getActiveSession() {
        org.eclipse.persistence.sessions.Session activeSession = getActiveUnitOfWork();
        if (activeSession == null) {
            activeSession = this;
        }

        return activeSession;
    }

    /**
     * PUBLIC:
     * Return the active unit of work for the current active external (JTS) transaction.
     * This should only be used with JTS and will return null if no external transaction exists.
     */
    @Override
    public org.eclipse.persistence.sessions.UnitOfWork getActiveUnitOfWork() {
        if (hasExternalTransactionController()) {
            return getExternalTransactionController().getActiveUnitOfWork();
        }

        /* Steven Vo:  CR# 2517
           Get from the server session since the external transaction controller could be
           null out from the client session by TL WebLogic 5.1 to provide non-jts transaction
           operations
          */
        if (isClientSession()) {
            return ((org.eclipse.persistence.sessions.server.ClientSession)this).getParent().getActiveUnitOfWork();
        }

        return null;
    }

    /**
     * INTERNAL:
     * Returns the alias descriptors Map.
     */
    public Map getAliasDescriptors() {
        return project.getAliasDescriptors();
    }

    /**
     * ADVANCED:
     * Answers the past time this session is as of.  Indicates whether or not this
     * is a special historical session where all objects are read relative to a
     * particular point in time.
     * @return An immutable object representation of the past time.
     * <code>null</code> if no clause set, or this a regular session.
     * @see #acquireHistoricalSession(org.eclipse.persistence.history.AsOfClause)
     */
    @Override
    public AsOfClause getAsOfClause() {
        return null;
    }

    /**
     * INTERNAL:
     * Allow the session to be used from a session broker.
     */
    public AbstractSession getBroker() {
        return broker;
    }

    /**
     * INTERNAL:
     * The session that this query is executed against when not in transaction.
     * The session containing the shared identity map.
     * <p>
     * In most cases this is the root ServerSession or DatabaseSession.
     * <p>
     * In cases where objects are not to be cached in the global identity map
     * an alternate session may be returned:
     * <ul>
     * <li>A ClientSession if in transaction
     * <li>An isolated ClientSession or HistoricalSession
     * <li>A registered session of a root SessionBroker
     * </ul>
     */
    public AbstractSession getRootSession(DatabaseQuery query) {
        ClassDescriptor descriptor = null;
        if (query != null){
            descriptor = query.getDescriptor();
        }
        return getParentIdentityMapSession(descriptor, true, true);
    }

    /**
     * INTERNAL:
     * Gets the parent session.
     */
    public AbstractSession getParent() {
        return null;
    }

    /**
     * INTERNAL:
     * Gets the next link in the chain of sessions followed by a query's check
     * early return, the chain of sessions with identity maps all the way up to
     * the root session.
     */
    public AbstractSession getParentIdentityMapSession(DatabaseQuery query) {
        ClassDescriptor descriptor = null;
        if (query != null){
            descriptor = query.getDescriptor();
        }
        return getParentIdentityMapSession(descriptor, false, false);
    }

    /**
     * INTERNAL:
     * Gets the next link in the chain of sessions followed by a query's check
     * early return, the chain of sessions with identity maps all the way up to
     * the root session.
     * <p>
     * Used for session broker which delegates to registered sessions, or UnitOfWork
     * which checks parent identity map also.
     * @param canReturnSelf true when method calls itself.  If the path
     * starting at <code>this</code> is acceptable.  Sometimes true if want to
     * move to the first valid session, i.e. executing on ClientSession when really
     * should be on ServerSession.
     * @param terminalOnly return the session we will execute the call on, not
     * the next step towards it.
     * @return this if there is no next link in the chain
     */
    public AbstractSession getParentIdentityMapSession(DatabaseQuery query, boolean canReturnSelf, boolean terminalOnly) {
        ClassDescriptor descriptor = null;
        if (query != null){
            descriptor = query.getDescriptor();
        }
        return getParentIdentityMapSession(descriptor, canReturnSelf, terminalOnly);
    }

    /**
     * INTERNAL:
     * Returns the appropriate IdentityMap session for this descriptor.  Sessions can be
     * chained and each session can have its own Cache/IdentityMap.  Entities can be stored
     * at different levels based on Cache Isolation.  This method will return the correct Session
     * for a particular Entity class based on the Isolation Level and the attributes provided.
     *
     * @param canReturnSelf true when method calls itself.  If the path
     * starting at <code>this</code> is acceptable.  Sometimes true if want to
     * move to the first valid session, i.e. executing on ClientSession when really
     * should be on ServerSession.
     * @param terminalOnly return the last session in the chain where the Enitity is stored.
     * @return Session with the required IdentityMap
     */
    public AbstractSession getParentIdentityMapSession(ClassDescriptor descriptor, boolean canReturnSelf, boolean terminalOnly) {
        return this;
    }

    /**
     * INTERNAL:
     * Returns the default pessimistic lock timeout value.
     */
    public Integer getPessimisticLockTimeoutDefault() {
        return pessimisticLockTimeoutDefault;
    }

    public TimeUnit getPessimisticLockTimeoutUnitDefault() {
        return pessimisticLockTimeoutUnitDefault;
    }
    /**
     * PUBLIC:
     * Return the default query timeout for this session.
     * This timeout will apply to any queries that do not have a timeout set,
     * and that do not have a default timeout defined in their descriptor.
     */
    public int getQueryTimeoutDefault() {
        return queryTimeoutDefault;
    }

    public TimeUnit getQueryTimeoutUnitDefault() {
        return queryTimeoutUnitDefault;
    }

    @SuppressWarnings("unchecked")
    public <T> InjectionManager<T> getInjectionManager() {
        if (injectionManager == null){
            injectionManager = createInjectionManager(this.getProperty(PersistenceUnitProperties.CDI_BEANMANAGER));
        }
        return injectionManager;
    }

    /**
     * INTERNAL:
     * Gets the session which this query will be executed on.
     * Generally will be called immediately before the call is translated,
     * which is immediately before session.executeCall.
     * <p>
     * Since the execution session also knows the correct datasource platform
     * to execute on, it is often used in the mappings where the platform is
     * needed for type conversion, or where calls are translated.
     * <p>
     * Is also the session with the accessor.  Will return a ClientSession if
     * it is in transaction and has a write connection.
     * @return a session with a live accessor
     * @param query may store session name or reference class for brokers case
     */
    public AbstractSession getExecutionSession(DatabaseQuery query) {
        return this;
    }

    /**
     * INTERNAL:
     * Return if the commit manager has been set.
     */
    public boolean hasCommitManager() {
        return commitManager != null;
    }

    /**
     * INTERNAL:
     * The commit manager is used to resolve referential integrity on commits of multiple objects.
     * All brokered sessions share the same commit manager.
     */
    public CommitManager getCommitManager() {
        if (hasBroker()) {
            return getBroker().getCommitManager();
        }

        // PERF: lazy init, not always required, not required for client sessions
        if (commitManager == null) {
            commitManager = new CommitManager(this);
        }
        return commitManager;
    }

    /**
     * INTERNAL:
     * Returns the set of read-only classes that gets assigned to each newly created UnitOfWork.
     *
     * @see org.eclipse.persistence.sessions.Project#setDefaultReadOnlyClasses(Collection)
     */
    public Vector getDefaultReadOnlyClasses() {
        //Bug#3911318  All brokered sessions share the same DefaultReadOnlyClasses.
        if (hasBroker()) {
            return getBroker().getDefaultReadOnlyClasses();
        }
        return getProject().getDefaultReadOnlyClasses();
    }

    /**
     * ADVANCED:
     * Return the descriptor specified for the class.
     * If the class does not have a descriptor but implements an interface that is also implemented
     * by one of the classes stored in the map, that descriptor will be stored under the
     * new class. If a descriptor does not exist for the Class parameter, null is returned.
     * If the passed Class parameter is null, then null will be returned.
     */
    @Override
    public ClassDescriptor getClassDescriptor(Class theClass) {
        if (theClass == null) {
            return null;
        }
        return getDescriptor(theClass);
    }

    /**
     * ADVANCED:
     * Return the descriptor specified for the object's class.
     * If a descriptor does not exist for the Object parameter, null is returned.
     * If the passed Object parameter is null, then null will be returned.
     */
    @Override
    public ClassDescriptor getClassDescriptor(Object domainObject) {
        if (domainObject == null) {
            return null;
        }
        return getDescriptor(domainObject);
    }

    /**
     * PUBLIC:
     * Return the descriptor for  the alias.
     * UnitOfWork delegates this to the parent
     */
    @Override
    public ClassDescriptor getClassDescriptorForAlias(String alias) {
        return project.getDescriptorForAlias(alias);
    }

    /**
     * ADVANCED:
     * Return the descriptor specified for the class.
     * If the class does not have a descriptor but implements an interface that is also implemented
     * by one of the classes stored in the map, that descriptor will be stored under the
     * new class. If the passed Class is null, null will be returned.
     */
    @Override
    public ClassDescriptor getDescriptor(Class theClass) {
        if (theClass == null) {
            return null;
        }

        // Optimize descriptor lookup through caching the last one accessed.
        ClassDescriptor descriptor = this.lastDescriptorAccessed;
        if ((descriptor != null) && (descriptor.getJavaClass() == theClass)) {
            return descriptor;
        }

        if (this.descriptors != null) {
            descriptor = this.descriptors.get(theClass);
        } else {
            descriptor = this.project.getDescriptors().get(theClass);
        }

        if (descriptor == null) {
            if (hasBroker()) {
                // Also check the broker
                descriptor = getBroker().getDescriptor(theClass);
            }
            if (descriptor == null) {
                // Allow for an event listener to lazy register the descriptor for a class.
                if (this.eventManager != null) {
                    this.eventManager.missingDescriptor(theClass);
                }
                descriptor = getDescriptors().get(theClass);

                if (descriptor == null) {
                    // This allows for the correct descriptor to be found if the class implements an interface,
                    // or extends a class that a descriptor is registered for.
                    // This is used by EJB to find the descriptor for a stub and remote to unwrap it,
                    // and by inheritance to allow for subclasses that have no additional state to not require a descriptor.
                    if (!theClass.isInterface()) {
                        Class[] interfaces = theClass.getInterfaces();
                        for (int index = 0; index < interfaces.length; ++index) {
                            Class interfaceClass = interfaces[index];
                            descriptor = getDescriptor(interfaceClass);
                            if (descriptor != null) {
                                getDescriptors().put(interfaceClass, descriptor);
                                break;
                            }
                        }
                        if (descriptor == null ) {
                            descriptor = checkHierarchyForDescriptor(theClass);
                        }
                    }
                }
            }
        }

        // Cache for optimization.
        this.lastDescriptorAccessed = descriptor;

        return descriptor;
    }

    /**
     * ADVANCED:
     * Return the descriptor specified for the object's class.
     * If the passed Object is null, null will be returned.
     */
    @Override
    public ClassDescriptor getDescriptor(Object domainObject) {
        if (domainObject == null) {
            return null;
        }
        //Bug#3947714  Check and trigger the proxy here
        if (this.project.hasProxyIndirection()) {
            return getDescriptor(ProxyIndirectionPolicy.getValueFromProxy(domainObject).getClass());
        }
        return getDescriptor(domainObject.getClass());
    }

    /**
     * PUBLIC:
     * Return the descriptor for the alias.
     * @param alias The descriptor alias.
     * @return The descriptor for the alias or {@code null} if no descriptor was found.
     */
    @Override
    public ClassDescriptor getDescriptorForAlias(final String alias) {
        // If we have a descriptors list return our sessions descriptor and
        // not that of the project since we may be dealing with a multitenant
        // descriptor which will have been initialized locally on the session.
        // The project descriptor will be not initialized.
        final ClassDescriptor desc = project.getDescriptorForAlias(alias);
        if (desc != null && desc.hasMultitenantPolicy() && this.descriptors != null) {
            return this.descriptors.get(desc.getJavaClass());
        } else {
            return desc;
        }
    }

    /**
     * ADVANCED:
     * Return all registered descriptors.
     */
    @Override
    public Map<Class, ClassDescriptor> getDescriptors() {
        return this.project.getDescriptors();
    }

    /**
     * INTERNAL:
     * Return if an event manager has been set.
     */
    public boolean hasEventManager() {
        return eventManager != null;
    }

    /**
     * PUBLIC:
     * Return the event manager.
     * The event manager can be used to register for various session events.
     */
    @Override
    public SessionEventManager getEventManager() {
        if (eventManager == null) {
            synchronized (this) {
                if (eventManager == null) {
                    // PERF: lazy init.
                    eventManager = new SessionEventManager(this);
                }
            }
        }
        return eventManager;
    }

    /**
     * INTERNAL:
     * Return a string which represents my ExceptionHandler's class
     * Added for F2104: Properties.xml
     * - gn
     */
    public String getExceptionHandlerClass() {
        String className = null;
        try {
            className = getExceptionHandler().getClass().getName();
        } catch (Exception exception) {
            return null;
        }
        return className;
    }

    /**
     * PUBLIC:
     * Return the ExceptionHandler.Exception handler can catch errors that occur on queries or during database access.
     */
    @Override
    public ExceptionHandler getExceptionHandler() {
        return exceptionHandler;
    }

    /**
     * PUBLIC:
     * Used for JTS integration.  If your application requires to have JTS control transactions instead of EclipseLink an
     * external transaction controller must be specified.
     * EclipseLink provides JTS controllers for several JTS implementations including JTS 1.0, Weblogic 5.1 and WebSphere 3.0.
     *
     * @see org.eclipse.persistence.transaction.JTATransactionController
     */
    @Override
    public ExternalTransactionController getExternalTransactionController() {
        return externalTransactionController;
    }

    /**
     * PUBLIC:
     * The IdentityMapAccessor is the preferred way of accessing IdentityMap funcitons
     * This will return an object which implements an interface which exposes all public
     * IdentityMap functions.
     */
    @Override
    public org.eclipse.persistence.sessions.IdentityMapAccessor getIdentityMapAccessor() {
        return identityMapAccessor;
    }

    /**
     * INTERNAL:
     * Return the internally available IdentityMapAccessor instance.
     */
    public org.eclipse.persistence.internal.sessions.IdentityMapAccessor getIdentityMapAccessorInstance() {
        return identityMapAccessor;
    }

    /**
     * PUBLIC:
     * Returns the integrityChecker.IntegrityChecker holds all the ClassDescriptor Exceptions.
     */
    @Override
    public IntegrityChecker getIntegrityChecker() {
        // BUG# 2700595 - Lazily create an IntegrityChecker if one has not already been created.
        if (integrityChecker == null) {
            integrityChecker = new IntegrityChecker();
        }

        return integrityChecker;
    }

    /**
     * ADVANCED:
     * Return all pre-defined not yet parsed JPQL queries.
     */
    @Override
    public List<DatabaseQuery> getJPAQueries() {
        return getProject().getJPAQueries();
    }

    /**
     * ADVANCED:
     * Return all pre-defined not yet parsed JPQL queries.
     */
    public List<DatabaseQuery> getJPATablePerTenantQueries() {
        return getProject().getJPATablePerTenantQueries();
    }

    /**
     * PUBLIC:
     * Return the writer to which an accessor writes logged messages and SQL.
     * If not set, this reference defaults to a writer on System.out.
     * To enable logging, logMessages must be turned on.
     *
     * @see #setLoggingOff(boolean) 
     */
    @Override
    public Writer getLog() {
        return getSessionLog().getWriter();
    }

    /**
     * INTERNAL:
     * Return the name of the session: class name + system hashcode.
     * <p>
     * This should be the implementation of toString(), and also the
     * value should be calculated in the constructor for it is used all the
     * time.  However everything is lazily initialized now and the value is
     * transient for the system hashcode could vary?
     */
    public String getLogSessionString() {
        if (logSessionString == null) {
            StringWriter writer = new StringWriter();
            writer.write(getSessionTypeString());
            writer.write("(");
            writer.write(String.valueOf(System.identityHashCode(this)));
            writer.write(")");
            logSessionString = writer.toString();
        }
        return logSessionString;
    }

    /**
     * INTERNAL:
     * Returns the type of session, its class.
     * <p>
     * Override to hide from the user when they are using an internal subclass
     * of a known class.
     * <p>
     * A user does not need to know that their UnitOfWork is a
     * non-deferred UnitOfWork, or that their ClientSession is an
     * IsolatedClientSession.
     */
    public String getSessionTypeString() {
        return Helper.getShortClassName(getClass());
    }

    /**
     * INTERNAL:
     * Return the static metamodel class associated with the given model class
     * if available. Callers must handle null.
     */
    public String getStaticMetamodelClass(String modelClassName) {
        if (staticMetamodelClasses != null) {
            return staticMetamodelClasses.get(modelClassName);
        }

        return null;
    }

    /**
     * OBSOLETE:
     * Return the login, the login holds any database connection information given.
     * This has been replaced by getDatasourceLogin to make use of the Login interface
     * to support non-relational datasources,
     * if DatabaseLogin API is required it will need to be cast.
     */
    @Override
    public DatabaseLogin getLogin() {
        try {
            return (DatabaseLogin)getDatasourceLogin();
        } catch (ClassCastException wrongType) {
            throw ValidationException.notSupportedForDatasource();
        }
    }

    /**
     * PUBLIC:
     * Return the login, the login holds any database connection information given.
     * This return the Login interface and may need to be cast to the datasource specific implementation.
     */
    @Override
    public Login getDatasourceLogin() {
        if (this.project == null) {
            return null;
        }
        return this.project.getDatasourceLogin();
    }

    /**
     * INTERNAL:
     * Return the mapped superclass descriptor if one exists for the given
     * class name. Must check any broker as well.
     */
    public ClassDescriptor getMappedSuperclass(String className) {
        ClassDescriptor desc = getProject().getMappedSuperclass(className);

        if (desc == null && hasBroker()) {
            getBroker().getMappedSuperclass(className);
        }

        return desc;
    }

    /**
     * PUBLIC:
     * Return a set of multitenant context properties this session
     */
    public Set<String> getMultitenantContextProperties() {
        if (this.multitenantContextProperties == null) {
            this.multitenantContextProperties = new HashSet<>();
        }

        return this.multitenantContextProperties;
    }

    /**
     * PUBLIC:
     * Return the name of the session.
     * This is used with the session broker, or to give the session a more meaningful name.
     */
    @Override
    public String getName() {
        return name;
    }

    /**
     * ADVANCED:
     * Return the sequnce number from the database
     */
    @Override
    public Number getNextSequenceNumberValue(Class domainClass) {
        return (Number)getSequencing().getNextValue(domainClass);
    }

    /**
     * INTERNAL:
     * Return the number of units of work connected.
     */
    public int getNumberOfActiveUnitsOfWork() {
        return numberOfActiveUnitsOfWork;
    }

    /**
     * INTERNAL:
     * For use within the merge process this method will get an object from the shared
     * cache using a readlock.  If a readlock is unavailable then the merge manager will be
     * transitioned to deferred locks and a deferred lock will be used.
     */
    protected CacheKey getCacheKeyFromTargetSessionForMerge(Object implementation, ObjectBuilder builder, ClassDescriptor descriptor, MergeManager mergeManager){
      Object original = null;
       Object primaryKey = builder.extractPrimaryKeyFromObject(implementation, this, true);
       if (primaryKey == null) {
           return null;
       }
       CacheKey cacheKey = null;
       if (mergeManager == null){
           cacheKey = getIdentityMapAccessorInstance().getCacheKeyForObject(primaryKey, implementation.getClass(), descriptor, true);
           if (cacheKey != null){
               cacheKey.checkReadLock();
           }
           return cacheKey;
       }

       cacheKey = getIdentityMapAccessorInstance().getCacheKeyForObject(primaryKey, implementation.getClass(), descriptor, true);
       if (cacheKey != null) {
           if (cacheKey.acquireReadLockNoWait()) {
               original = cacheKey.getObject();
               cacheKey.releaseReadLock();
           } else {
               if (!mergeManager.isTransitionedToDeferredLocks()) {
                   getIdentityMapAccessorInstance().getWriteLockManager().transitionToDeferredLocks(mergeManager);
               }
               cacheKey.acquireDeferredLock();
               original = cacheKey.getObject();
               if (original == null) {
                   synchronized (cacheKey) {
                       if (cacheKey.isAcquired()) {
                           try {
                               cacheKey.wait();
                           } catch (InterruptedException e) {
                               //ignore and return
                           }
                       }
                       original = cacheKey.getObject();
                   }
               }
               cacheKey.releaseDeferredLock();
           }
       }
       return cacheKey;
    }

    /**
     * INTERNAL:
     * Return the database platform currently connected to.
     * The platform is used for database specific behavior.
     * NOTE: this must only be used for relational specific usage,
     * it will fail for non-relational datasources.
     */
    @Override
    public DatabasePlatform getPlatform() {
        // PERF: Cache the platform.
        if (platform == null) {
            platform = getDatasourceLogin().getPlatform();
        }
        return (DatabasePlatform)platform;
    }


    /**
     * INTERNAL:
     * Return the class loader for the session's application.
     * This loader should be able to load any application or EclipseLink class.
     */
    public ClassLoader getLoader() {
        return getDatasourcePlatform().getConversionManager().getLoader();
    }

    /**
     * INTERNAL:
     * Return the database platform currently connected to.
     * The platform is used for database specific behavior.
     */
    @Override
    public Platform getDatasourcePlatform() {
        // PERF: Cache the platform.
        if (platform == null) {
            platform = getDatasourceLogin().getDatasourcePlatform();
        }
        return platform;
    }

    /**
     * INTERNAL:
     * Marked internal as this is not customer API but helper methods for
     * accessing the server platform from within EclipseLink's other sessions types
     * (ie not DatabaseSession)
     */
    @Override
    public ServerPlatform getServerPlatform() {
        return null;
    }

    /**
     * INTERNAL:
     * Return the database platform currently connected to
     * for specified class.
     * The platform is used for database specific behavior.
     */
    @Override
    public Platform getPlatform(Class domainClass) {
        // PERF: Cache the platform.
        if (platform == null) {
            platform = getDatasourcePlatform();
        }
        return platform;
    }

    /**
     * PUBLIC:
     * Return the profiler.
     * The profiler is a tool that can be used to determine performance bottlenecks.
     * The profiler can be queries to print summaries and configure for logging purposes.
     */
    @Override
    public SessionProfiler getProfiler() {
        return profiler;
    }

    /**
     * PUBLIC:
     * Return the project, the project holds configuartion information including the descriptors.
     */
    @Override
    public org.eclipse.persistence.sessions.Project getProject() {
        return project;
    }

    /**
     * ADVANCED:
     * Allow for user defined properties.
     */
    @Override
    public Map<String, Object> getProperties() {
        if (properties == null) {
            properties = new HashMap(5);
        }
        return properties;
    }

    /**
     * INTERNAL:
     * Allow to check for user defined properties.
     */
    public boolean hasProperties() {
        return ((properties != null) && !properties.isEmpty());
    }

    /**
     * INTERNAL:
     * Return list of table per tenant multitenant descriptors.
     */
    public boolean hasTablePerTenantDescriptors() {
        return (tablePerTenantDescriptors != null && ! tablePerTenantDescriptors.isEmpty());
    }

    /**
     * INTERNAL:
     * Return a list of table per tenant multitenant queries.
     */
    public boolean hasTablePerTenantQueries() {
        return (tablePerTenantQueries != null && ! tablePerTenantQueries.isEmpty());
    }

    /**
     * ADVANCED:
     * Returns the user defined property.
     */
    @Override
    public Object getProperty(String name) {
        if(this.properties==null){
            return null;
        }
        return getProperties().get(name);
    }

    /**
     * ADVANCED:
     * Return all pre-defined queries.
     */
    @Override
    public Map<String, List<DatabaseQuery>> getQueries() {
        // PERF: lazy init, not normally required.
        if (queries == null) {
            queries = new HashMap(5);
        }
        return queries;
    }

    /**
     * ADVANCED:
     * Return an attribute group of a particular name.
     */

    /**
     * ADVANCED
     * Return all predefined attribute groups
     */
    public Map<String, AttributeGroup> getAttributeGroups(){
        if (this.attributeGroups == null){
            this.attributeGroups = new HashMap<>(5);
        }
        return this.attributeGroups;
    }

    /**
     * INTERNAL:
     * Return the pre-defined queries in this session.
     * A single vector containing all the queries is returned.
     *
     * @see #getQueries()
     */
    public List<DatabaseQuery> getAllQueries() {
        Vector allQueries = new Vector();
        for (Iterator vectors = getQueries().values().iterator(); vectors.hasNext();) {
            allQueries.addAll((Vector)vectors.next());
        }
        return allQueries;
    }

    /**
     * PUBLIC:
     * Return the query from the session pre-defined queries with the given name.
     * This allows for common queries to be pre-defined, reused and executed by name.
     */
    @Override
    public DatabaseQuery getQuery(String name) {
        return getQuery(name, null);
    }

    /**
     * PUBLIC:
     * Return the query from the session pre-defined queries with the given name and argument types.
     * This allows for common queries to be pre-defined, reused and executed by name.
     * This method should be used if the Session has multiple queries with the same name but
     * different arguments.
     *
     * @see #getQuery(String)
     */
    @Override
    public DatabaseQuery getQuery(String name, List arguments) {
        if (arguments instanceof Vector) {
            return getQuery(name, (Vector)arguments);
        } else {
            return getQuery(name, new Vector(arguments));
        }
    }

    /**
     * PUBLIC:
     * Return the query from the session pre-defined queries with the given name and argument types.
     * This allows for common queries to be pre-defined, reused and executed by name.
     * This method should be used if the Session has multiple queries with the same name but
     * different arguments.
     *
     * @see #getQuery(String)
     */
    public DatabaseQuery getQuery(String name, Vector arguments) {
        return getQuery(name, arguments, true);
    }

    /**
     * INTERNAL:
     * Return the query from the session pre-defined queries with the given name and argument types.
     * This allows for common queries to be pre-defined, reused and executed by name.
     * This method should be used if the Session has multiple queries with the same name but
     * different arguments.
     *
     * @param shouldSearchParent indicates whether parent should be searched if query not found.
     * @see #getQuery(String, List)
     */
    public DatabaseQuery getQuery(String name, Vector arguments, boolean shouldSearchParent) {
        Vector queries = (Vector)getQueries().get(name);
        if ((queries != null) && !queries.isEmpty()) {
            // Short circuit the simple, most common case of only one query.
            if (queries.size() == 1) {
                return (DatabaseQuery)queries.firstElement();
            }

            // CR#3754; Predrag; mar 19/2002;
            // We allow multiple named queries with the same name but
            // different argument set; we can have only one query with
            // no arguments; Vector queries is not sorted;
            // When asked for the query with no parameters the
            // old version did return the first query - wrong:
            // return (DatabaseQuery) queries.firstElement();
            int argumentTypesSize = 0;
            if (arguments != null) {
                argumentTypesSize = arguments.size();
            }
            Vector argumentTypes = new Vector(argumentTypesSize);
            for (int i = 0; i < argumentTypesSize; i++) {
                argumentTypes.addElement(arguments.elementAt(i).getClass());
            }
            for (Enumeration queriesEnum = queries.elements(); queriesEnum.hasMoreElements();) {
                DatabaseQuery query = (DatabaseQuery)queriesEnum.nextElement();
                if (Helper.areTypesAssignable(argumentTypes, query.getArgumentTypes())) {
                    return query;
                }
            }
        }
        if(shouldSearchParent) {
            AbstractSession parent = getParent();
            if(parent != null) {
                return parent.getQuery(name, arguments, true);
            }
        }
        return null;
    }

    /**
     * Returns an AttributeGroup by name
     */

    /**
     * INTERNAL:
     * Return the Sequencing object used by the session.
     */
    public Sequencing getSequencing() {
        return null;
    }

    /**
     * INTERNAL:
     * Return the session to be used for the class.
     * Used for compatibility with the session broker.
     */
    public AbstractSession getSessionForClass(Class domainClass) {
        if (hasBroker()) {
            return getBroker().getSessionForClass(domainClass);
        }
        return this;
    }

    /**
     * INTERNAL:
     * Return the session by name.
     * Used for compatibility with the session broker.
     */
    public AbstractSession getSessionForName(String name) throws ValidationException {
        if (hasBroker()) {
            return getBroker().getSessionForName(name);
        }
        return this;
    }

    /**
     * PUBLIC:
     * Return the session log to which an accessor logs messages and SQL.
     * If not set, this will default to a session log on a writer on System.out.
     * To enable logging, logMessages must be turned on.
     *
     * @see #setLoggingOff(boolean) 
     */
    @Override
    public SessionLog getSessionLog() {
        if (sessionLog == null) {
            setSessionLog(new DefaultSessionLog());
        }
        return sessionLog;
    }

    /**
     * INTERNAL:
     * Return list of table per tenant multitenant descriptors.
     */
    public List<ClassDescriptor> getTablePerTenantDescriptors() {
        if (tablePerTenantDescriptors == null) {
            tablePerTenantDescriptors = new ArrayList<>();
        }

        return tablePerTenantDescriptors;
    }

    /**
     * INTERNAL:
     * Return list of table per tenant multitenant descriptors.
     */
    public List<DatabaseQuery> getTablePerTenantQueries() {
        if (tablePerTenantQueries == null) {
            tablePerTenantQueries = new ArrayList<>();
        }

        return tablePerTenantQueries;
    }

    /**
     * INTERNAL:
     * The transaction mutex ensure mutual exclusion on transaction across multiple threads.
     */
    public ConcurrencyManager getTransactionMutex() {
        // PERF: not always required, defer.
        if (transactionMutex == null) {
            synchronized (this) {
                if (transactionMutex == null) {
                    transactionMutex = new ConcurrencyManager();
                }
            }
        }
        return transactionMutex;
    }

    /**
     * PUBLIC:
     * Allow any WARNING level exceptions that occur within EclipseLink to be logged and handled by the exception handler.
     */
    @Override
    public Object handleException(RuntimeException exception) throws RuntimeException {
        if ((exception instanceof EclipseLinkException)) {
            EclipseLinkException eclipseLinkException = (EclipseLinkException)exception;
            if (eclipseLinkException.getSession() == null) {
                eclipseLinkException.setSession(this);
            }

            //Bug#3559280  Avoid logging an exception twice
            if (!eclipseLinkException.hasBeenLogged()) {
                logThrowable(SessionLog.WARNING, null, exception);
                eclipseLinkException.setHasBeenLogged(true);
            }
        } else {
            logThrowable(SessionLog.WARNING, null, exception);
        }
        if (hasExceptionHandler()) {
            if (this.broker != null && this.broker.hasExceptionHandler()) {
                try {
                    return getExceptionHandler().handleException(exception);
                } catch (RuntimeException ex) {
                    // handle the original exception
                    return this.broker.getExceptionHandler().handleException(exception);
                }
            } else {
                return getExceptionHandler().handleException(exception);
            }
        } else {
            if (this.broker != null && this.broker.hasExceptionHandler()) {
                return this.broker.getExceptionHandler().handleException(exception);
            } else {
                throw exception;
            }
        }
    }

    /**
     * INTERNAL:
     * Allow the session to be used from a session broker.
     */
    public boolean hasBroker() {
        return broker != null;
    }


    /**
     * ADVANCED:
     * Return true if a descriptor exists for the given class.
     */
    @Override
    public boolean hasDescriptor(Class theClass) {
        if (theClass == null) {
            return false;
        }

        return getDescriptors().get(theClass) != null;
    }

    /**
     * PUBLIC:
     * Return if an exception handler is present.
     */
    @Override
    public boolean hasExceptionHandler() {
        if (exceptionHandler == null) {
            return false;
        }
        return true;
    }

    /**
     * PUBLIC:
     * Used for JTA integration.  If your application requires to have JTA control transactions instead of EclipseLink an
     * external transaction controler must be specified.  EclipseLink provides JTA controlers for JTA 1.0 and application
     * servers.
     * @see org.eclipse.persistence.transaction.JTATransactionController
     */
    @Override
    public boolean hasExternalTransactionController() {
        return externalTransactionController != null;
    }


    /**
     * INTERNAL:
     * Set up the IdentityMapManager.  This method allows subclasses of Session to override
     * the default IdentityMapManager functionality.
     */
    public void initializeIdentityMapAccessor() {
        this.identityMapAccessor = new org.eclipse.persistence.internal.sessions.IdentityMapAccessor(this, new IdentityMapManager(this));
    }

    /**
     * PUBLIC:
     * Insert the object and all of its privately owned parts into the database.
     * Insert should only be used if the application knows that the object is new,
     * otherwise writeObject should be used.
     * The insert operation can be customized through using an insert query.
     *
     * @exception DatabaseException if an error occurs on the database,
     * these include constraint violations, security violations and general database errors.
     *
     * @see InsertObjectQuery
     * @see #writeObject(Object)
     */
    public Object insertObject(Object domainObject) throws DatabaseException {
        InsertObjectQuery query = new InsertObjectQuery();
        query.setObject(domainObject);
        query.setIsExecutionClone(true);
        return executeQuery(query);
    }

    /**
     * INTERNAL:
     * Return the results from exeucting the database query.
     * The arguments should be a database row with raw data values.
     * This method is provided to allow subclasses to change the default querying behavior.
     * All querying goes through this method.
     */
    public Object internalExecuteQuery(DatabaseQuery query, AbstractRecord databaseRow) throws DatabaseException {
        return query.execute(this, databaseRow);
    }

    /**
     * INTERNAL:
     * Returns true if the session is a session Broker.
     */
    public boolean isBroker() {
        return false;
    }

    /**
     * INTERNAL:
     * Returns true if the session is in a session Broker.
     */
    public boolean isInBroker() {
        return isInBroker;
    }

    /**
     * PUBLIC:
     * Return if the class is defined as read-only.
     */
    public boolean isClassReadOnly(Class theClass) {
        ClassDescriptor descriptor = getDescriptor(theClass);
        return isClassReadOnly(theClass, descriptor);
    }

    /**
     * INTERNAL:
     * Return if the class is defined as read-only.
     * PERF: Pass descriptor to avoid re-lookup.
     */
    public boolean isClassReadOnly(Class theClass, ClassDescriptor descriptor) {
        if ((descriptor != null) && descriptor.shouldBeReadOnly()) {
            return true;
        }
        if (theClass != null) {
            return getDefaultReadOnlyClasses().contains(theClass);
        }
        return false;
    }

    /**
     * PUBLIC:
     * Return if this session is a client session.
     */
    @Override
    public boolean isClientSession() {
        return false;
    }

    /**
     * PUBLIC:
     * Return if this session is an isolated client session.
     */
    public boolean isIsolatedClientSession() {
        return false;
    }

    /**
     * PUBLIC:
     * Return if this session is an exclusive isolated client session.
     */
    public boolean isExclusiveIsolatedClientSession() {
        return false;
    }

    /**
     * PUBLIC:
     * Return if this session is connected to the database.
     */
    @Override
    public boolean isConnected() {
        if (getAccessor() == null) {
            return false;
        }

        return getAccessor().isConnected();
    }

    /**
     * PUBLIC:
     * Return if this session is a database session.
     */
    @Override
    public boolean isDatabaseSession() {
        return false;
    }

    /**
     * PUBLIC:
     * Return if this session is a distributed session.
     */
    @Override
    public boolean isDistributedSession() {
        return false;
    }

    /**
     * PUBLIC:
     * Return if a profiler is being used.
     */
    @Override
    public boolean isInProfile() {
        return isInProfile;
    }

    /**
     * PUBLIC:
     * Allow for user deactive a profiler
     */
    public void setIsInProfile(boolean inProfile) {
        this.isInProfile = inProfile;
    }

    /**
     * INTERNAL:
     * Set if this session is contained in a SessionBroker.
     */
    public void setIsInBroker(boolean isInBroker) {
        this.isInBroker = isInBroker;
    }

    /**
     * PUBLIC:
     * Return if this session's decendants should use finalizers.
     * The allows certain finalizers such as in ClientSession to be enabled.
     * These are disable by default for performance reasons.
     */
    @Override
    public boolean isFinalizersEnabled() {
        return isFinalizersEnabled;
    }

    /**
     * INTERNAL:
     * Register a finalizer to release this session.
     */
    public void registerFinalizer() {
        // Ensure the finalizer is referenced until the session is gc'd.
        setProperty("finalizer", new SessionFinalizer(this));
    }

    /**
     * INTERNAL:
     * Return if this session is a historical session.
     */
    public boolean isHistoricalSession() {
        return false;
    }

    /**
     * PUBLIC:
     * Set if this session's decendants should use finalizers.
     * The allows certain finalizers such as in ClientSession to be enabled.
     * These are disable by default for performance reasons.
     */
    @Override
    public void setIsFinalizersEnabled(boolean isFinalizersEnabled) {
        this.isFinalizersEnabled = isFinalizersEnabled;
    }

    /**
     * PUBLIC:
     * Return if the session is currently in the progress of a database transaction.
     * Because nested transactions are allowed check if the transaction mutex has been aquired.
     */
    public boolean isInTransaction() {
        return this.transactionMutex != null && this.transactionMutex.isAcquired();
    }

    /**
     * INTERNAL:
     * used to see if JPA Queries have been processed during initialization
     */
    public boolean isJPAQueriesProcessed(){
        return this.jpaQueriesProcessed;
    }

    /**
     * PUBLIC:
     * Returns true if Protected Entities should be built within this session
     */
    public boolean isProtectedSession(){
        return true;
    }

    /**
     * PUBLIC:
     * Return if this session is remote.
     */
    @Override
    public boolean isRemoteSession() {
        return false;
    }

    /**
     * PUBLIC:
     * Return if this session is a unit of work.
     */
    @Override
    public boolean isRemoteUnitOfWork() {
        return false;
    }

    /**
     * PUBLIC:
     * Return if this session is a server session.
     */
    @Override
    public boolean isServerSession() {
        return false;
    }

    /**
     * PUBLIC:
     * Return if this session is a session broker.
     */
    @Override
    public boolean isSessionBroker() {
        return false;
    }

    /**
     * INTERNAL:
     * Return if this session is synchronized.
     */
    public boolean isSynchronized() {
        return isSynchronized;
    }

    /**
     * PUBLIC:
     * Return if this session is a unit of work.
     */
    @Override
    public boolean isUnitOfWork() {
        return false;
    }

    /**
     * ADVANCED:
     * Extract and return the primary key from the object.
     */
    @Override
    public Object getId(Object domainObject) throws ValidationException {
        ClassDescriptor descriptor = getDescriptor(domainObject);
        return keyFromObject(domainObject, descriptor);
    }

    /**
     * ADVANCED:
     * Extract and return the primary key from the object.
     */
    public Object keyFromObject(Object domainObject, ClassDescriptor descriptor) throws ValidationException {
        if (descriptor == null) {
            throw ValidationException.missingDescriptor(domainObject.getClass().getName());
        }
        Object implemention = descriptor.getObjectBuilder().unwrapObject(domainObject, this);
        if (implemention == null) {
            return null;
        }
        return descriptor.getObjectBuilder().extractPrimaryKeyFromObject(implemention, this);
    }

    /**
     * PUBLIC:
     * Log the log entry.
     */
    @Override
    public void log(SessionLogEntry entry) {
        if (this.isLoggingOff) {
            return;
        }
        if (shouldLog(entry.getLevel(), entry.getNameSpace())) {
            if (entry.getSession() == null) {// Used for proxy session.
                entry.setSession(this);
            }
            getSessionLog().log(entry);
        }
    }

    /**
     * Log a untranslated message to the EclipseLink log at FINER level.
     */
    @Override
    public void logMessage(String message) {
        if (this.isLoggingOff) {
            return;
        }
        log(SessionLog.FINER, SessionLog.MISC, message, null, null, false);
    }

    /**
     * INTERNAL:
     * A call back to do session specific preparation of a query.
     * <p>
     * The call back occurs soon before we clone the query for execution,
     * meaning that if this method needs to clone the query then the caller will
     * determine that it doesn't need to clone the query itself.
     */
    public DatabaseQuery prepareDatabaseQuery(DatabaseQuery query) {
        if (!isUnitOfWork() && query.isObjectLevelReadQuery()) {
            return ((ObjectLevelReadQuery)query).prepareOutsideUnitOfWork(this);
        } else {
            return query;
        }
    }


    /**
     * PUBLIC:
     * Read all of the instances of the class from the database.
     * This operation can be customized through using a ReadAllQuery,
     * or through also passing in a selection criteria.
     *
     * @see ReadAllQuery
     * @see #readAllObjects(Class, Expression)
     */
    @Override
    public Vector readAllObjects(Class domainClass) throws DatabaseException {
        ReadAllQuery query = new ReadAllQuery();
        query.setIsExecutionClone(true);
        query.setReferenceClass(domainClass);
        return (Vector)executeQuery(query);
    }

    /**
     * PUBLIC:
     * Read all of the instances of the class from the database return through execution the SQL string.
     * The SQL string must be a valid SQL select statement or selecting stored procedure call.
     * This operation can be customized through using a ReadAllQuery.
      * Warning: Allowing an unverified SQL string to be passed into this
     * method makes your application vulnerable to SQL injection attacks.
     *
     * @see ReadAllQuery
     */
    public Vector readAllObjects(Class domainClass, String sqlString) throws DatabaseException {
        ReadAllQuery query = new ReadAllQuery();
        query.setReferenceClass(domainClass);
        query.setSQLString(sqlString);
        query.setIsExecutionClone(true);
        return (Vector)executeQuery(query);
    }

    /**
     * PUBLIC:
     * Read all the instances of the class from the database returned through execution the Call string.
     * The Call can be an SQLCall or JPQLCall.
     *
     * example: session.readAllObjects(Employee.class, new SQLCall("SELECT * FROM EMPLOYEE"));
     * @see Call
     */
    @Override
    public Vector readAllObjects(Class referenceClass, Call aCall) throws DatabaseException {
        ReadAllQuery raq = new ReadAllQuery();
        raq.setReferenceClass(referenceClass);
        raq.setCall(aCall);
        raq.setIsExecutionClone(true);
        return (Vector)executeQuery(raq);
    }

    /**
     * PUBLIC:
     * Read all of the instances of the class from the database matching the given expression.
     * This operation can be customized through using a ReadAllQuery.
     *
     * @see ReadAllQuery
     */
    @Override
    public Vector readAllObjects(Class domainClass, Expression expression) throws DatabaseException {
        ReadAllQuery query = new ReadAllQuery();
        query.setReferenceClass(domainClass);
        query.setSelectionCriteria(expression);
        query.setIsExecutionClone(true);
        return (Vector)executeQuery(query);
    }

    /**
     * PUBLIC:
     * Read the first instance of the class from the database.
     * This operation can be customized through using a ReadObjectQuery,
     * or through also passing in a selection criteria.
     *
     * @see ReadObjectQuery
     * @see #readAllObjects(Class, Expression)
     */
    @Override
    public Object readObject(Class domainClass) throws DatabaseException {
        ReadObjectQuery query = new ReadObjectQuery();
        query.setReferenceClass(domainClass);
        query.setIsExecutionClone(true);
        return executeQuery(query);
    }

    /**
     * PUBLIC:
     * Read the first instance of the class from the database return through execution the SQL string.
     * The SQL string must be a valid SQL select statement or selecting stored procedure call.
     * This operation can be customized through using a ReadObjectQuery.
      * Warning: Allowing an unverified SQL string to be passed into this
     * method makes your application vulnerable to SQL injection attacks.
     *
     * @see ReadObjectQuery
     */
    public Object readObject(Class domainClass, String sqlString) throws DatabaseException {
        ReadObjectQuery query = new ReadObjectQuery();
        query.setReferenceClass(domainClass);
        query.setSQLString(sqlString);
        query.setIsExecutionClone(true);
        return executeQuery(query);
    }

    /**
     * PUBLIC:
     * Read the first instance of the class from the database returned through execution the Call string.
     * The Call can be an SQLCall or JPQLCall.
     *
     * example: session.readObject(Employee.class, new SQLCall("SELECT * FROM EMPLOYEE"));
     * @see SQLCall
     * @see JPQLCall
     */
    @Override
    public Object readObject(Class domainClass, Call aCall) throws DatabaseException {
        ReadObjectQuery query = new ReadObjectQuery();
        query.setReferenceClass(domainClass);
        query.setCall(aCall);
        query.setIsExecutionClone(true);
        return executeQuery(query);
    }

    /**
     * PUBLIC:
     * Read the first instance of the class from the database matching the given expression.
     * This operation can be customized through using a ReadObjectQuery.
     *
     * @see ReadObjectQuery
     */
    @Override
    public Object readObject(Class domainClass, Expression expression) throws DatabaseException {
        ReadObjectQuery query = new ReadObjectQuery();
        query.setReferenceClass(domainClass);
        query.setSelectionCriteria(expression);
        query.setIsExecutionClone(true);
        return executeQuery(query);
    }

    /**
     * PUBLIC:
     * Use the example object to consruct a read object query by the objects primary key.
     * This will read the object from the database with the same primary key as the object
     * or null if no object is found.
     */
    @Override
    public Object readObject(Object object) throws DatabaseException {
        ReadObjectQuery query = new ReadObjectQuery();
        query.setSelectionObject(object);
        query.setIsExecutionClone(true);
        return executeQuery(query);
    }

    /**
     * PUBLIC:
     * Refresh the attributes of the object and of all of its private parts from the database.
     * The object will be pessimisticly locked on the database for the duration of the transaction.
     * If the object is already locked this method will wait until the lock is released.
     * A no wait option is available through setting the lock mode.
     * @see #refreshAndLockObject(Object, short)
     */
    public Object refreshAndLockObject(Object object) throws DatabaseException {
        return refreshAndLockObject(object, ObjectBuildingQuery.LOCK);
    }

    /**
     * PUBLIC:
     * Refresh the attributes of the object and of all of its private parts from the database.
     * The object will be pessimisticly locked on the database for the duration of the transaction.
     * <p>Lock Modes: ObjectBuildingQuery.NO_LOCK, LOCK, LOCK_NOWAIT
     */
    public Object refreshAndLockObject(Object object, short lockMode) throws DatabaseException {
        ReadObjectQuery query = new ReadObjectQuery();
        query.setSelectionObject(object);
        query.refreshIdentityMapResult();
        query.cascadePrivateParts();
        query.setLockMode(lockMode);
        query.setIsExecutionClone(true);
        return executeQuery(query);
    }

    /**
     * PUBLIC:
     * Refresh the attributes of the object and of all of its private parts from the database.
     * This can be used to ensure the object is up to date with the database.
     * Caution should be used when using this to make sure the application has no un commited
     * changes to the object.
     */
    @Override
    public Object refreshObject(Object object) throws DatabaseException {
        return refreshAndLockObject(object, ObjectBuildingQuery.NO_LOCK);
    }

    /**
     * PUBLIC:
     * Release the session.
     * This does nothing by default, but allows for other sessions such as the ClientSession to do something.
     */
    @Override
    public void release() {
    }

    /**
     * INTERNAL:
     * Release the unit of work, if lazy release the connection.
     */
    public void releaseUnitOfWork(UnitOfWorkImpl unitOfWork) {
        // Nothing is required by default, allow subclasses to do cleanup.
        setNumberOfActiveUnitsOfWork(getNumberOfActiveUnitsOfWork() - 1);
    }


    /**
     * PUBLIC:
     * Remove the user defined property.
     */
    @Override
    public void removeProperty(String property) {
        getProperties().remove(property);
    }

    /**
     * PUBLIC:
     * Remove all queries with the given queryName regardless of the argument types.
     *
     * @see #removeQuery(String, Vector)
     */
    @Override
    public void removeQuery(String queryName) {
        getQueries().remove(queryName);
    }

    /**
     * PUBLIC:
     * Remove the specific query with the given queryName and argumentTypes.
     */
    public void removeQuery(String queryName, Vector argumentTypes) {
        Vector queries = (Vector)getQueries().get(queryName);
        if (queries == null) {
            return;
        } else {
            DatabaseQuery query = null;
            for (Enumeration enumtr = queries.elements(); enumtr.hasMoreElements();) {
                query = (DatabaseQuery)enumtr.nextElement();
                if (Helper.areTypesAssignable(argumentTypes, query.getArgumentTypes())) {
                    break;
                }
            }
            if (query != null) {
                queries.remove(query);
            }
        }
    }

    /**
     * PROTECTED:
     * Attempts to rollback the running internally started external transaction.
     * Returns true only in one case -
     * extenal transaction has been internally rolled back during this method call:
     * wasJTSTransactionInternallyStarted()==true in the beginning of this method and
     * wasJTSTransactionInternallyStarted()==false in the end of this method.
     */
    protected boolean rollbackExternalTransaction() {
        boolean externalTransactionHasRolledBack = false;
        if (hasExternalTransactionController() && wasJTSTransactionInternallyStarted()) {
            try {
                getExternalTransactionController().rollbackTransaction(this);
            } catch (RuntimeException exception) {
                handleException(exception);
            }
            if (!wasJTSTransactionInternallyStarted()) {
                externalTransactionHasRolledBack = true;
                log(SessionLog.FINER, SessionLog.TRANSACTION, "external_transaction_has_rolled_back_internally");
            }
        }
        return externalTransactionHasRolledBack;
    }

    /**
     * PUBLIC:
     * Rollback the active database transaction.
     * This allows a group of database modification to be commited or rolledback as a unit.
     * All writes/deletes will be sent to the database be will not be visible to other users until commit.
     * Although databases do not allow nested transaction,
     * EclipseLink supports nesting through only committing to the database on the outer commit.
     *
     * @exception DatabaseException if the database connection is lost or the rollback fails.
     * @exception ConcurrencyException if this session is not within a transaction.
     */
    public void rollbackTransaction() throws DatabaseException, ConcurrencyException {
        ConcurrencyManager mutex = getTransactionMutex();
        // Ensure release of mutex and call subclass specific release.
        try {
            if (!mutex.isNested()) {
                if (this.eventManager != null) {
                    this.eventManager.preRollbackTransaction();
                }
                basicRollbackTransaction();
                if (this.eventManager != null) {
                    this.eventManager.postRollbackTransaction();
                }
            }
        } finally {
            mutex.release();

            // If there is no db transaction in progress
            // if there is an active external transaction
            // which was started internally - it should be rolled back internally, too.
            if (!mutex.isAcquired()) {
                rollbackExternalTransaction();
            }
        }
    }

    /**
     * INTERNAL:
     * Set the accessor.
     */
    public void setAccessor(Accessor accessor) {
        this.accessors = new ArrayList(1);
        this.accessors.add(accessor);
    }

    /**
     * INTERNAL:
     * Allow the session to be used from a session broker.
     */
    public void setBroker(AbstractSession broker) {
        this.broker = broker;
    }


    /**
     * INTERNAL:
     * The commit manager is used to resolve referncial integrity on commits of multiple objects.
     */
    public void setCommitManager(CommitManager commitManager) {
        this.commitManager = commitManager;
    }

    public void setInjectionManager(
            InjectionManager injectionManager) {
        this.injectionManager = injectionManager;
    }

    /**
     * INTERNAL:
     * Set the event manager.
     * The event manager can be used to register for various session events.
     */
    public void setEventManager(SessionEventManager eventManager) {
        this.eventManager = eventManager;
        if (eventManager != null) {
            this.eventManager.setSession(this);
        }
    }

    /**
     * PUBLIC:
     * Set the exceptionHandler.
     * Exception handler can catch errors that occur on queries or during database access.
     */
    @Override
    public void setExceptionHandler(ExceptionHandler exceptionHandler) {
        this.exceptionHandler = exceptionHandler;
    }

    /**
     * Used for JTS integration internally by ServerPlatform.
     */
    @Override
    public void setExternalTransactionController(ExternalTransactionController externalTransactionController) {
        this.externalTransactionController = externalTransactionController;
        if (externalTransactionController == null) {
            return;
        }
        if (!hasBroker()) {
            externalTransactionController.setSession(this);
        }
    }

    /**
     * PUBLIC:
     * set the integrityChecker. IntegrityChecker holds all the ClassDescriptor Exceptions.
     */
    @Override
    public void setIntegrityChecker(IntegrityChecker integrityChecker) {
        this.integrityChecker = integrityChecker;
    }

    /**
     * INTERNAL:
     * used to set if JPA Queries have been processed during initialization
     */
    public void setJPAQueriesProcessed(boolean jpaQueriesProcessed){
        this.jpaQueriesProcessed = jpaQueriesProcessed;
    }

    /**
     * PUBLIC:
     * Set the writer to which an accessor writes logged messages and SQL.
     * If not set, this reference defaults to a writer on System.out.
     * To enable logging logMessages() is used.
     *
     * @see #setLoggingOff(boolean) 
     */
    @Override
    public void setLog(Writer log) {
        getSessionLog().setWriter(log);
    }

    /**
     * PUBLIC:
     * Set the login.
     */
    public void setLogin(DatabaseLogin login) {
        setDatasourceLogin(login);
    }

    /**
     * PUBLIC:
     * Set the login.
     */
    public void setLogin(Login login) {
        setDatasourceLogin(login);
    }

    /**
     * PUBLIC:
     * Set the login.
     */
    public void setDatasourceLogin(Login login) {
        getProject().setDatasourceLogin(login);
        this.platform = null;
    }

    /**
     * PUBLIC:
     * Set the name of the session.
     * This is used with the session broker.
     */
    @Override
    public void setName(String name) {
        this.name = name;
    }

    protected void setNumberOfActiveUnitsOfWork(int numberOfActiveUnitsOfWork) {
        this.numberOfActiveUnitsOfWork = numberOfActiveUnitsOfWork;
    }

    /**
     * PUBLIC:
     * Set the default pessimistic lock timeout value. This value will be used
     * to set the WAIT clause of a SQL SELECT FOR UPDATE statement. It defines
     * how long EcliseLink should wait for a lock on the database row before
     * aborting.
     */
    public void setPessimisticLockTimeoutDefault(Integer pessimisticLockTimeoutDefault) {
        this.pessimisticLockTimeoutDefault = pessimisticLockTimeoutDefault;
    }
    
    public void setPessimisticLockTimeoutUnitDefault(TimeUnit pessimisticLockTimeoutUnitDefault) {
        this.pessimisticLockTimeoutUnitDefault = pessimisticLockTimeoutUnitDefault;
    }
    /**
     * PUBLIC:
     * Set the default query timeout for this session.
     * This timeout will apply to any queries that do not have a timeout set,
     * and that do not have a default timeout defined in their descriptor.
     */
    @Override
    public void setQueryTimeoutDefault(int queryTimeoutDefault) {
        this.queryTimeoutDefault = queryTimeoutDefault;
    }

    @Override
    public void setQueryTimeoutUnitDefault(TimeUnit queryTimeoutUnitDefault) {
        this.queryTimeoutUnitDefault = queryTimeoutUnitDefault;
    }

    /**
     * PUBLIC:
     * Set the profiler for the session.
     * This allows for performance operations to be profiled.
     */
    @Override
    public void setProfiler(SessionProfiler profiler) {
        this.profiler = profiler;
        if (profiler != null) {
            profiler.setSession(this);
            setIsInProfile(getProfiler().getProfileWeight() != SessionProfiler.NONE);
            // Clear cached flag that bypasses the profiler check.
            getIdentityMapAccessorInstance().getIdentityMapManager().checkIsCacheAccessPreCheckRequired();
        } else {
            setIsInProfile(false);
        }
    }

    /**
     * INTERNAL:
     * Set the project, the project holds configuration information including the descriptors.
     */
    public void setProject(org.eclipse.persistence.sessions.Project project) {
        this.project = project;
    }

    /**
     * INTERNAL:
     * Set the user defined properties by shallow copying the propertiesMap.
     */
    public void setProperties(Map<String, Object> propertiesMap) {
        if (null == propertiesMap) {
            // Keep current behavior and set properties map to null
            properties = null;
        } else {
            /*
             * Bug# 219097 Clone as (HashMap) possible immutable maps to avoid
             * an UnsupportedOperationException on a later put() We do not know
             * the key:value type values at design time. putAll() is not
             * synchronized. We clone all maps whether immutable or not.
             */
            properties = new HashMap();
            // Shallow copy all internal key:value pairs - a null propertiesMap will throw a NPE
            properties.putAll(propertiesMap);
        }
    }

    /**
     * PUBLIC: Allow for user defined properties.
     */
    @Override
    public void setProperty(String propertyName, Object propertyValue) {
        getProperties().put(propertyName, propertyValue);
    }

    /**
     * INTERNAL:
     * Set the named queries.
     */
    public void setQueries(Map<String, List<DatabaseQuery>> queries) {
        this.queries = queries;
    }

    /**
     * PUBLIC:
     * Set the session log to which an accessor logs messages and SQL.
     * If not set, this will default to a session log on a writer on System.out.
     * To enable logging, log level can not be OFF.
     * Also set a backpointer to this session in SessionLog.
     *
     * @see #logMessage(String)
     */
    @Override
    public void setSessionLog(SessionLog sessionLog) {
        this.isLoggingOff = false;
        this.sessionLog = sessionLog;
        if ((sessionLog != null) && (sessionLog.getSession() == null)) {
            sessionLog.setSession(this);
        }
    }

    /**
     * INTERNAL:
     * Set isSynchronized flag to indicate that this session is synchronized.
     * This method should only be called by setSynchronized methods of derived classes.
     */
    public void setSynchronized(boolean synched) {
        isSynchronized = synched;
    }

    protected void setTransactionMutex(ConcurrencyManager transactionMutex) {
        this.transactionMutex = transactionMutex;
    }

    /**
     * INTERNAL:
     * Return if a JTS transaction was started by the session.
     * The session will start a JTS transaction if a unit of work or transaction is begun without a JTS transaction present.
     */
    public void setWasJTSTransactionInternallyStarted(boolean wasJTSTransactionInternallyStarted) {
        this.wasJTSTransactionInternallyStarted = wasJTSTransactionInternallyStarted;
    }

    /**
     * PUBLIC:
     * Return if logging is enabled (false if log level is OFF)
     */
    @Override
    public boolean shouldLogMessages() {
        if (this.isLoggingOff) {
            return false;
        }
        if (getLogLevel(null) == SessionLog.OFF) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * INTERNAL:
     * Start the operation timing.
     */
    @Override
    public void startOperationProfile(String operationName) {
        if (this.isInProfile) {
            getProfiler().startOperationProfile(operationName);
        }
    }

    /**
     * INTERNAL:
     * Start the operation timing.
     */
    public void startOperationProfile(String operationName, DatabaseQuery query, int weight) {
        if (this.isInProfile) {
            getProfiler().startOperationProfile(operationName, query, weight);
        }
    }

    /**
     * Print the connection status with the session.
     */
    @Override
    public String toString() {
        StringWriter writer = new StringWriter();
        writer.write(getSessionTypeString() + "(" + Helper.cr() + "\t" + getAccessor() + Helper.cr() + "\t" + getDatasourcePlatform() + ")");
        return writer.toString();
    }

    /**
     * INTERNAL:
     * Unwrap the object if required.
     * This is used for the wrapper policy support and EJB.
     */
    public Object unwrapObject(Object proxy) {
        return getDescriptor(proxy).getObjectBuilder().unwrapObject(proxy, this);
    }

    /**
     * PUBLIC:
     * Update the object and all of its privately owned parts in the database.
     * Update should only be used if the application knows that the object is new,
     * otherwise writeObject should be used.
     * The update operation can be customized through using an update query.
     *
     * @exception DatabaseException if an error occurs on the database,
     * these include constraint violations, security violations and general database errors.
     * @exception OptimisticLockException if the object's descriptor is using optimistic locking and
     * the object has been updated or deleted by another user since it was last read.
     *
     * @see UpdateObjectQuery
     * @see #writeObject(Object)
     */
    public Object updateObject(Object domainObject) throws DatabaseException, OptimisticLockException {
        UpdateObjectQuery query = new UpdateObjectQuery();
        query.setObject(domainObject);
        query.setIsExecutionClone(true);
        return executeQuery(query);
    }

    /**
     * ADVANCED:
     * This can be used to help debugging an object identity problem.
     * An object identity problem is when an object in the cache references an object not in the cache.
     * This method will validate that all cached objects are in a correct state.
     */
    @Override
    public void validateCache() {
        getIdentityMapAccessorInstance().validateCache();
    }

    /**
     * INTERNAL:
     * This method will be used to update the query with any settings required
     * For this session.  It can also be used to validate execution.
     */
    public void validateQuery(DatabaseQuery query) {
        // a no-op for this class
    }

    /**
     * TESTING:
     * This is used by testing code to ensure that a deletion was successful.
     */
    public boolean verifyDelete(Object domainObject) {
        ObjectBuilder builder = getDescriptor(domainObject).getObjectBuilder();
        Object implementation = builder.unwrapObject(domainObject, this);

        return builder.verifyDelete(implementation, this);
    }

    /**
     * INTERNAL:
     * Return if a JTS transaction was started by the session.
     * The session will start a JTS transaction if a unit of work or transaction is begun without a JTS transaction present.
     */
    public boolean wasJTSTransactionInternallyStarted() {
        return wasJTSTransactionInternallyStarted;
    }

    /**
     * INTERNAL:
     * Wrap the object if required.
     * This is used for the wrapper policy support and EJB.
     */
    public Object wrapObject(Object implementation) {
        return getDescriptor(implementation).getObjectBuilder().wrapObject(implementation, this);
    }

    /**
     * INTERNAL:
     * Write all of the objects and all of their privately owned parts in the database.
     * The allows for a group of new objects to be commited as a unit.
     * The objects will be commited through a single transactions and any
     * foreign keys/circular references between the objects will be resolved.
     */
    protected void writeAllObjectsWithChangeSet(UnitOfWorkChangeSet uowChangeSet) throws DatabaseException, OptimisticLockException {
        getCommitManager().commitAllObjectsWithChangeSet(uowChangeSet);
    }

    /**
     * PUBLIC:
     * Write the object and all of its privately owned parts in the database.
     * Write will determine if an insert or an update should be done,
     * it may go to the database to determine this (by default will check the identity map).
     * The write operation can be customized through using an write query.
     *
     * @exception DatabaseException if an error occurs on the database,
     * these include constraint violations, security violations and general database errors.
     * @exception OptimisticLockException if the object's descriptor is using optimistic locking and
     * the object has been updated or deleted by another user since it was last read.
     *
     * @see WriteObjectQuery
     * @see #insertObject(Object)
     * @see #updateObject(Object)
     */
    public Object writeObject(Object domainObject) throws DatabaseException, OptimisticLockException {
        WriteObjectQuery query = new WriteObjectQuery();
        query.setObject(domainObject);
        query.setIsExecutionClone(true);
        return executeQuery(query);
    }

    /**
     * INTERNAL:
     * This method notifies the accessor that a particular sets of writes has
     * completed.  This notification can be used for such thing as flushing the
     * batch mechanism
     */
    public void writesCompleted() {
        if (getAccessors() == null) {
            return;
        }
        for (Accessor accessor : getAccessors()) {
            accessor.writesCompleted(this);
    }
    }

    /**
      * INTERNAL:
      * RemoteCommandManager method. This is a required method in order
      * to implement the CommandProcessor interface.
      * Process the remote command from the RCM. The command may have come from
      * any remote session or application. Since this is a EclipseLink session we can
      * always assume that the object that we receive here will be a Command object.
      */
    @Override
    public void processCommand(Object command) {
        ((Command)command).executeWithSession(this);
    }

    /**
     * INTERNAL:
     * Process the JPA named queries into EclipseLink Session queries. This
     * method is called after descriptor initialization.
     * Temporarily made public for ODI. Should not be used elsewhere.
     */
    public void processJPAQueries() {
        if (! jpaQueriesProcessed) {
            // Process the JPA queries that do not query table per tenant entities.
            for (DatabaseQuery jpaQuery : getJPAQueries()) {
                processJPAQuery(jpaQuery);
            }

            // Process the JPA queries that query table per tenant entities. At
            // the EMF level, these queries will be initialized and added right
            // away. At the EM level we must defer their initialization to each
            // individual client session.
            for (DatabaseQuery jpaQuery : getJPATablePerTenantQueries()) {
                boolean processQuery = true;

                for (ClassDescriptor descriptor : jpaQuery.getDescriptors()) {
                    // If the descriptor is not fully initialized then we can
                    // not initialize the query and must isolate it to be
                    // initialized and stored per client session (EM).
                    if (! descriptor.isFullyInitialized()) {
                        processQuery = false;
                        break;
                    }
                }

                if (processQuery) {
                    processJPAQuery(jpaQuery);
                } else {
                    addTablePerTenantQuery(jpaQuery);
                }
            }

            jpaQueriesProcessed = true;
        }
    }

    /**
     * INTERNAL:
     * Process the JPA named query into an EclipseLink Session query. This
     * method is called after descriptor initialization.
     */
    protected void processJPAQuery(DatabaseQuery jpaQuery) {
        // This is a hack, to allow the core Session to initialize JPA queries, without have a dependency on JPA.
        // They need to be initialized after login, as the database platform must be known.
        try {
            jpaQuery.prepareInternal(this);
        } catch (RuntimeException re) {
            // If jpql-tolerate-error==true, any problems will be ignored at query prep time and the runtime will
            // continue chugging along. The invalid query will be left in place so that an exception
            // will be thrown at runtime if a user attempts to use it.
            if (!tolerateInvalidJPQL) {
                throw re;
            }
        }
        DatabaseQuery databaseQuery = (DatabaseQuery) jpaQuery.getProperty("databasequery");
        databaseQuery = (databaseQuery == null) ? jpaQuery : databaseQuery;
        addQuery(databaseQuery, false); // this should be true but for backward compatibility it
                                        // is set to false.
    }

    /**
     * PUBLIC:
     * Return the CommandManager that allows this session to act as a
     * CommandProcessor and receive or propagate commands from/to the
     * EclipseLink cluster.
     *
     * @see CommandManager
     * @return The CommandManager instance that controls the remote command
     * service for this session
     */
    @Override
    public CommandManager getCommandManager() {
        return commandManager;
    }

    /**
     * ADVANCED:
     * Set the CommandManager that allows this session to act as a
     * CommandProcessor and receive or propagate commands from/to the
     * EclipseLink cluster.
     *
     * @see CommandManager
     * @param mgr The CommandManager instance to control the remote command
     * service for this session
     */
    @Override
    public void setCommandManager(CommandManager mgr) {
        commandManager = mgr;
    }

    /**
     * PUBLIC:
     * Return whether changes should be propagated to other sessions or applications
     * in a EclipseLink cluster through the Remote Command Manager mechanism. In order for
     * this to occur the CommandManager must be set.
     *
     * @see #setCommandManager(CommandManager)
     * @return True if propagation is set to occur, false if not
     */
    public boolean shouldPropagateChanges() {
        return shouldPropagateChanges;
    }

    /**
     * ADVANCED:
     * Set whether changes should be propagated to other sessions or applications
     * in a EclipseLink cluster through the Remote Command Manager mechanism. In order for
     * this to occur the CommandManager must be set.
     *
     * @see #setCommandManager(CommandManager)
     * @param choice If true (and the CommandManager is set) then propagation will occur
     */
    public void setShouldPropagateChanges(boolean choice) {
        shouldPropagateChanges = choice;
    }

    /**
     * INTERNAL:
     * RemoteCommandManager method. This is a required method in order
     * to implement the CommandProcessor interface.
     * Return true if a message at the specified log level would be logged given the
     * log level setting of this session. This can be used by the CommandManager to
     * know whether it should even bother to create the localized strings and call
     * the logMessage method, or if it would only find that the message would not be
     * logged because the session level does not permit logging. The log level passed
     * in will be one of the constants LOG_ERROR, LOG_WARNING, LOG_INFO, and LOG_DEBUG
     * defined in the CommandProcessor interface.
     */
    @Override
    public boolean shouldLogMessages(int logLevel) {
        if (this.isLoggingOff) {
            return false;
        }
        if (LOG_ERROR == logLevel) {
            return getLogLevel(SessionLog.PROPAGATION) <= SessionLog.SEVERE;
        }
        if (LOG_WARNING == logLevel) {
            return getLogLevel(SessionLog.PROPAGATION) <= SessionLog.WARNING;
        }
        if (LOG_INFO == logLevel) {
            return getLogLevel(SessionLog.PROPAGATION) <= SessionLog.FINER;
        }
        if (LOG_DEBUG == logLevel) {
            return getLogLevel(SessionLog.PROPAGATION) <= SessionLog.FINEST;
        }
        return false;
    }

    /**
     * INTERNAL:
     * RemoteCommandManager method. This is a required method in order
     * to implement the CommandProcessor interface.
     * Log the specified message string at the specified level if it should be logged
     * given the log level setting in this session. The log level passed in will be one
     * of the constants LOG_ERROR, LOG_WARNING, LOG_INFO, and LOG_DEBUG defined in the
     * CommandProcessor interface.
     */
    @Override
    public void logMessage(int logLevel, String message) {
        if (this.isLoggingOff) {
            return;
        }
        if (shouldLogMessages(logLevel)) {
            int level;
            switch (logLevel) {
            case CommandProcessor.LOG_ERROR:
                level = SessionLog.SEVERE;
                break;
            case CommandProcessor.LOG_WARNING:
                level = SessionLog.WARNING;
                break;
            case CommandProcessor.LOG_INFO:
                level = SessionLog.FINER;
                break;
            case CommandProcessor.LOG_DEBUG:
                level = SessionLog.FINEST;
                break;
            default:
                level = SessionLog.ALL;
            }
            log(level, SessionLog.PROPAGATION, message, null, null, false);
        }
    }

    /**
     * PUBLIC:
     * <p>
     * Return the log level
     * </p>
     *
     * @return the log level
     * @param category  the string representation of a EclipseLink category, e.g. "sql", "transaction" ...
     */
    @Override
    public int getLogLevel(String category) {
        return getSessionLog().getLevel(category);
    }

    /**
     * PUBLIC:
     * <p>
     * Return the log level
     * </p>
     * @return the log level
     */
    @Override
    public int getLogLevel() {
        return getSessionLog().getLevel();
    }

    /**
     * PUBLIC:
     * <p>
     * Set the log level
     * </p>
     *
     * @param level     the new log level
     */
    @Override
    public void setLogLevel(int level) {
        this.isLoggingOff = false;
        getSessionLog().setLevel(level);
    }

    /**
     * PUBLIC:
     * Return true if SQL logging should log visible bind parameters. If the
     * shouldDisplayData is not set, check the session log level and return
     * true for a level greater than CONFIG.
     */
    public boolean shouldDisplayData() {
        return getSessionLog().shouldDisplayData();
    }

    /**
     * PUBLIC:
     * <p>
     * Check if a message of the given level would actually be logged.</p>
     *
     * @return true if the given message level will be logged
     * @param level  the log request level
     * @param category  the string representation of a EclipseLink category
     */
    @Override
    public boolean shouldLog(int level, String category) {
        if (this.isLoggingOff) {
            return false;
        }
        return getSessionLog().shouldLog(level, category);
    }

    /**
     * PUBLIC:
     * <p>
     * Log a message with level and category that needs to be translated.
     * </p>
     *
     * @param level  the log request level value
     * @param message  the string message
     * @param category  the string representation of a EclipseLink category.
     */
    public void log(int level, String category, String message) {
        if (this.isLoggingOff) {
            return;
        }
        if (!shouldLog(level, category)) {
            return;
        }
        log(level, category, message, null);
    }

    /**
     * PUBLIC:
     * <p>
     * Log a message with level, category and a parameter that needs to be translated.
     * </p>
     *
     * @param level  the log request level value
     * @param message  the string message
     * @param category  the string representation of a EclipseLink category.
     * @param param  a parameter of the message
     */
    public void log(int level, String category, String message, Object param) {
        if (this.isLoggingOff) {
            return;
        }
        if (!shouldLog(level, category)) {
            return;
        }
        log(level, category, message, new Object[] { param });
    }

    /**
     * PUBLIC:
     * <p>
     * Log a message with level, category and two parameters that needs to be translated.
     * </p>
     *
     * @param level  the log request level value
     * @param message  the string message
     * @param category  the string representation of a EclipseLink category.
     * @param param1  a parameter of the message
     * @param param2  second parameter of the message
     */
    public void log(int level, String category, String message, Object param1, Object param2) {
        if (this.isLoggingOff) {
            return;
        }
        if (!shouldLog(level, category)) {
            return;
        }
        log(level, category, message, new Object[] { param1, param2 });
    }

    /**
     * PUBLIC:
     * <p>
     * Log a message with level, category and three parameters that needs to be translated.
     * </p>
     *
     * @param level  the log request level value
     * @param message  the string message
     * @param category  the string representation of a EclipseLink category.
     * @param param1  a parameter of the message
     * @param param2  second parameter of the message
     * @param param3  third parameter of the message
     */
    public void log(int level, String category, String message, Object param1, Object param2, Object param3) {
        if (this.isLoggingOff) {
            return;
        }
        if (!shouldLog(level, category)) {
            return;
        }
        log(level, category, message, new Object[] { param1, param2, param3 });
    }

    /**
     * PUBLIC:
     * <p>
     * Log a message with level, category and an array of parameters that needs to be translated.
     * </p>
     *
     * @param level  the log request level value
     * @param message  the string message
     * @param category  the string representation of a EclipseLink category.
     * @param params  array of parameters to the message
     */
    public void log(int level, String category, String message, Object[] params) {
        if (this.isLoggingOff) {
            return;
        }
        log(level, category, message, params, null);
    }

    /**
     * PUBLIC:
     * <p>
     * Log a message with level, category, parameters and accessor that needs to be translated.
     * </p>
     *
     * @param level  the log request level value
     * @param message  the string message
     * @param params  array of parameters to the message
     * @param accessor  the connection that generated the log entry
     * @param category  the string representation of a EclipseLink category.
     */
    public void log(int level, String category, String message, Object[] params, Accessor accessor) {
        if (this.isLoggingOff) {
            return;
        }
        log(level, category, message, params, accessor, true);
    }

    /**
     * PUBLIC:
     * <p>
     * Log a message with level, category, parameters and accessor.  shouldTranslate determines if the message needs to be translated.
     * </p>
     *
     * @param level  the log request level value
     * @param message  the string message
     * @param params  array of parameters to the message
     * @param accessor  the connection that generated the log entry
     * @param category  the string representation of a EclipseLink category.
     * @param shouldTranslate  true if the message needs to be translated.
     */
    public void log(int level, String category, String message, Object[] params, Accessor accessor, boolean shouldTranslate) {
        if (this.isLoggingOff) {
            return;
        }
        if (shouldLog(level, category)) {
            startOperationProfile(SessionProfiler.Logging);
            log(new SessionLogEntry(level, category, this, message, params, accessor, shouldTranslate));
            endOperationProfile(SessionProfiler.Logging);
        }
    }

    /**
     * PUBLIC:
     * <p>
     * Log a throwable with level and category.
     * </p>
     *
     * @param level  the log request level value
     * @param category  the string representation of a EclipseLink category.
     * @param throwable  a Throwable
     */
    public void logThrowable(int level, String category, Throwable throwable) {
        if (this.isLoggingOff) {
            return;
        }
        // Must not create the log if not logging as is a performance issue.
        if (shouldLog(level, category)) {
            startOperationProfile(SessionProfiler.Logging);
            log(new SessionLogEntry(this, level, category, throwable));
            endOperationProfile(SessionProfiler.Logging);
        }
    }

    /**
     * PUBLIC:
     * <p>
     * This method is called when a severe level message needs to be logged.
     * The message will be translated
     * </p>
     *
     * @param message  the message key
     */
    public void severe(String message, String category) {
        if (this.isLoggingOff) {
            return;
        }
        log(SessionLog.SEVERE, category, message);
    }

    /**
     * PUBLIC:
     * <p>
     * This method is called when a warning level message needs to be logged.
     * The message will be translated
     * </p>
     *
     * @param message  the message key
     */
    public void warning(String message, String category) {
        if (this.isLoggingOff) {
            return;
        }
        log(SessionLog.WARNING, category, message);
    }

    /**
     * PUBLIC:
     * <p>
     * This method is called when a info level message needs to be logged.
     * The message will be translated
     * </p>
     *
     * @param message  the message key
     */
    public void info(String message, String category) {
        if (this.isLoggingOff) {
            return;
        }
        log(SessionLog.INFO, category, message);
    }

    /**
     * PUBLIC:
     * <p>
     * This method is called when a config level message needs to be logged.
     * The message will be translated
     * </p>
     *
     * @param message  the message key
     */
    public void config(String message, String category) {
        if (this.isLoggingOff) {
            return;
        }
        log(SessionLog.CONFIG, category, message);
    }

    /**
     * PUBLIC:
     * <p>
     * This method is called when a fine level message needs to be logged.
     * The message will be translated
     * </p>
     *
     * @param message  the message key
     */
    public void fine(String message, String category) {
        if (this.isLoggingOff) {
            return;
        }
        log(SessionLog.FINE, category, message);
    }

    /**
     * PUBLIC:
     * <p>
     * This method is called when a finer level message needs to be logged.
     * The message will be translated
     * </p>
     *
     * @param message  the message key
     */
    public void finer(String message, String category) {
        if (this.isLoggingOff) {
            return;
        }
        log(SessionLog.FINER, category, message);
    }

    /**
     * PUBLIC:
     * <p>
     * This method is called when a finest level message needs to be logged.
     * The message will be translated
     * </p>
     *
     * @param message  the message key
     */
    public void finest(String message, String category) {
        if (this.isLoggingOff) {
            return;
        }
        log(SessionLog.FINEST, category, message);
    }

    /**
     * PUBLIC:
     * Allow any SEVERE level exceptions that occur within EclipseLink to be logged and handled by the exception handler.
     */
    @Override
    public Object handleSevere(RuntimeException exception) throws RuntimeException {
        logThrowable(SessionLog.SEVERE, null, exception);
        if (hasExceptionHandler()) {
            return getExceptionHandler().handleException(exception);
        } else {
            throw exception;
        }
    }

    /**
      * INTERNAL:
      */
    public void releaseReadConnection(Accessor connection) {
        //bug 4668234 -- used to only release connections on server sessions but should always release
        //do nothing -- overidden in UnitOfWork,ClientSession and ServerSession
    }

    /**
     * INTERNAL:
     * Copies descriptors cached on the Project.
     * Used after Project.descriptors has been reset by addDescriptor(s) when the session is connected.
     */
   public void copyDescriptorsFromProject() {
       this.descriptors = getDescriptors();
   }

    /**
     * INTERNAL:
     * This method will be used to copy all EclipseLink named queries defined in descriptors into the session.
     * @param allowSameQueryNameDiffArgsCopyToSession  if the value is true, it allow
     * multiple queries of the same name but different arguments to be copied to the session.
     */
    public void copyDescriptorNamedQueries(boolean allowSameQueryNameDiffArgsCopyToSession) {
        for (ClassDescriptor descriptor : getProject().getOrderedDescriptors()) {
            Map queries  = descriptor.getQueryManager().getQueries();
            if ((queries != null) && (queries.size() > 0)) {
                for (Iterator keyValueItr = queries.entrySet().iterator(); keyValueItr.hasNext();){
                    Map.Entry entry = (Map.Entry) keyValueItr.next();
                    Vector thisQueries = (Vector)entry.getValue();
                    if ((thisQueries != null) && (thisQueries.size() > 0)){
                        for( Iterator thisQueriesItr=thisQueries.iterator();thisQueriesItr.hasNext();){
                            DatabaseQuery queryToBeAdded = (DatabaseQuery)thisQueriesItr.next();
                            if (allowSameQueryNameDiffArgsCopyToSession){
                                addQuery(queryToBeAdded, false);
                            } else {
                                if (getQuery(queryToBeAdded.getName()) == null){
                                    addQuery(queryToBeAdded, false);
                                } else {
                                    log(SessionLog.WARNING, SessionLog.PROPERTIES, "descriptor_named_query_cannot_be_added", new Object[]{queryToBeAdded,queryToBeAdded.getName(),queryToBeAdded.getArgumentTypes()});
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * INTERNAL:
     * This method rises appropriate for the session event(s)
     * right after connection is acquired.
     */
    public void postAcquireConnection(Accessor accessor) {
        if (getProject().hasVPDIdentifier(this)) {
            if (getPlatform().supportsVPD()) {
                DatabaseQuery query = getPlatform().getVPDSetIdentifierQuery(getProject().getVPDIdentifier());
                List argValues = new ArrayList();
                query.addArgument(getProject().getVPDIdentifier());
                argValues.add(getProperty(getProject().getVPDIdentifier()));
                executeQuery(query, argValues);
            } else {
                throw ValidationException.vpdNotSupported(getPlatform().getClass().getName());
            }
        }

        if (this.eventManager != null) {
            this.eventManager.postAcquireConnection(accessor);
        }
    }

    /**
     * INTERNAL:
     * This method rises appropriate for the session event(s)
     * right before the connection is released.
     */
    public void preReleaseConnection(Accessor accessor) {
        if (getProject().hasVPDIdentifier(this)) {
            if (getPlatform().supportsVPD()) {
                DatabaseQuery query = getPlatform().getVPDClearIdentifierQuery(getProject().getVPDIdentifier());
                List argValues = new ArrayList();
                query.addArgument(getProject().getVPDIdentifier());
                argValues.add(getProperty(getProject().getVPDIdentifier()));
                executeQuery(query, argValues);
            } else {
                throw ValidationException.vpdNotSupported(getPlatform().getClass().getName());
            }
        }

        if (this.eventManager != null) {
            this.eventManager.preReleaseConnection(accessor);
        }
    }

    /**
     * INTERNAL:
     * Execute the call on the database. Calling this method will bypass a
     * global setting to disallow native SQL queries. (set by default when
     * one Entity is marked as multitenant)
     *
     * The row count is returned.
     *
     * The call can be a stored procedure call, SQL call or other type of call.
     *
     * <p>Example:
     * <p>session.executeNonSelectingCall(new SQLCall("Delete from Employee"), true);
     *
     * @see #priviledgedExecuteSelectingCall(Call)
     */
    public int priviledgedExecuteNonSelectingCall(Call call) throws DatabaseException {
        DataModifyQuery query = new DataModifyQuery();
        query.setAllowNativeSQLQuery(true);
        query.setIsExecutionClone(true);
        query.setCall(call);
        Integer value = (Integer)executeQuery(query);
        if (value == null) {
            return 0;
        } else {
            return value;
        }
    }

    /**
     * INTERNAL:
     * Execute the call on the database and return the result. Calling this
     * method will bypass a global setting to disallow native SQL queries. (set
     * by default when one Entity is marked as multitenant)
     *
     * The call must return a value, if no value is return executeNonSelectCall
     * must be used.
     *
     * The call can be a stored procedure call, SQL call or other type of call.
     *
     * A vector of database rows is returned, database row implements Java 2 Map
     * which should be used to access the data.
     *
     * <p>Example:
     * <p>session.executeSelectingCall(new SQLCall("Select * from Employee");
     *
     * @see #priviledgedExecuteNonSelectingCall(Call)
     */
    public Vector priviledgedExecuteSelectingCall(Call call) throws DatabaseException {
        DataReadQuery query = new DataReadQuery();
        query.setAllowNativeSQLQuery(true);
        query.setCall(call);
        query.setIsExecutionClone(true);
        return (Vector)executeQuery(query);
    }

    /**
     * INTERNAL:
     * This method is called in case externalConnectionPooling is used.
     * If returns true, accessor used by the session keeps its
     * connection open until released by the session.
     */
    public boolean isExclusiveConnectionRequired() {
        return false;
    }

    /**
     *  Stores the default Session wide reference mode that a UnitOfWork will use when referencing
     *  managed objects.
     *  @see org.eclipse.persistence.config.ReferenceMode
     */
    @Override
    public ReferenceMode getDefaultReferenceMode() {
        return defaultReferenceMode;
    }

    /**
     *  Stores the default Session wide reference mode that a UnitOfWork will use when referencing
     *  managed objects.
     *  @see org.eclipse.persistence.config.ReferenceMode
     */
   @Override
   public void setDefaultReferenceMode(ReferenceMode defaultReferenceMode) {
        this.defaultReferenceMode = defaultReferenceMode;
    }

   /**
    * This method will load the passed object or collection of objects using the passed AttributeGroup.
    * In case of collection all members should be either objects of the same mapped type
    * or have a common inheritance hierarchy mapped root class.
    * The AttributeGroup should correspond to the object type.
    *
    */
   public void load(Object objectOrCollection, AttributeGroup group) {
       if (objectOrCollection == null || group == null) {
           return;
       }
       if (objectOrCollection instanceof Collection) {
           Iterator iterator = ((Collection)objectOrCollection).iterator();
           while (iterator.hasNext()) {
               Object object = iterator.next();
               load(object, group, getClassDescriptor(object.getClass()), false);
           }
       } else {
           ClassDescriptor concreteDescriptor =  getClassDescriptor(objectOrCollection.getClass());
           load(objectOrCollection, group, concreteDescriptor, false);
       }
   }

   /**
    * This method will load the passed object or collection of objects using the passed AttributeGroup.
    * In case of collection all members should be either objects of the same mapped type
    * or have a common inheritance hierarchy mapped root class.
    * The AttributeGroup should correspond to the object type.
    *
    */
   public void load(Object objectOrCollection, AttributeGroup group, ClassDescriptor referenceDescriptor, boolean fromFetchGroup) {
       if (objectOrCollection == null || group == null) {
           return;
       }
       if (objectOrCollection instanceof Collection) {
           Iterator iterator = ((Collection)objectOrCollection).iterator();
           while (iterator.hasNext()) {
               load(iterator.next(), group, referenceDescriptor, fromFetchGroup);
           }
       } else {
           ClassDescriptor concreteDescriptor = referenceDescriptor;
           if (concreteDescriptor.hasInheritance() && !objectOrCollection.getClass().equals(concreteDescriptor.getJavaClass())){
               concreteDescriptor = concreteDescriptor.getInheritancePolicy().getDescriptor(objectOrCollection.getClass());
           }
           AttributeGroup concreteGroup = group.findGroup(concreteDescriptor);
           concreteDescriptor.getObjectBuilder().load(objectOrCollection, concreteGroup, this, fromFetchGroup);
       }
   }

   public CacheKey retrieveCacheKey(Object primaryKey, ClassDescriptor concreteDescriptor, JoinedAttributeManager joinManager, ObjectBuildingQuery query){

       CacheKey cacheKey;
       //lock the object in the IM
       // PERF: Only use deferred locking if required.
       // CR#3876308 If joining is used, deferred locks are still required.
       if (query.requiresDeferredLocks()) {
           cacheKey = this.getIdentityMapAccessorInstance().acquireDeferredLock(primaryKey, concreteDescriptor.getJavaClass(), concreteDescriptor, query.isCacheCheckComplete() || query.shouldRetrieveBypassCache());

           if (cacheKey.getActiveThread() != Thread.currentThread()) {
               int counter = 0;
               while ((cacheKey.getObject() == null) && (counter < 1000)) {
                   //must release lock here to prevent acquiring multiple deferred locks but only
                   //releasing one at the end of the build object call.
                   //bug 5156075
                   cacheKey.releaseDeferredLock();
                   //sleep and try again if we are not the owner of the lock for CR 2317
                   // prevents us from modifying a cache key that another thread has locked.
                   try {
                       Thread.sleep(10);
                   } catch (InterruptedException exception) {
                   }
                   cacheKey = this.getIdentityMapAccessorInstance().acquireDeferredLock(primaryKey, concreteDescriptor.getJavaClass(), concreteDescriptor, query.isCacheCheckComplete() || query.shouldRetrieveBypassCache());
                   if (cacheKey.getActiveThread() == Thread.currentThread()) {
                       break;
                   }
                   counter++;
               }
               if (counter == 1000) {
                   throw ConcurrencyException.maxTriesLockOnBuildObjectExceded(cacheKey.getActiveThread(), Thread.currentThread());
               }
           }
       } else {
           cacheKey = this.getIdentityMapAccessorInstance().acquireLock(primaryKey, concreteDescriptor.getJavaClass(), concreteDescriptor, query.isCacheCheckComplete() || query.shouldRetrieveBypassCache());
       }
       return  cacheKey;
   }


   /**
    * PUBLIC:
    * Return the session's partitioning policy.
    */
   @Override
   public PartitioningPolicy getPartitioningPolicy() {
       return partitioningPolicy;
   }

   /**
    * PUBLIC:
    * Set the session's partitioning policy.
    * A PartitioningPolicy is used to partition, load-balance or replicate data across multiple difference databases
    * or across a database cluster such as Oracle RAC.
    * Partitioning can provide improved scalability by allowing multiple database machines to service requests.
    */
   @Override
   public void setPartitioningPolicy(PartitioningPolicy partitioningPolicy) {
       this.partitioningPolicy = partitioningPolicy;
   }

   /**
    * INTERNAL:
    * This currently only used by JPA with RCM to force a refresh of the metadata used within EntityManagerFactoryWrappers
    */
   public MetadataRefreshListener getRefreshMetadataListener() {
       return metadatalistener;
   }

   public void setRefreshMetadataListener(MetadataRefreshListener metadatalistener) {
       this.metadatalistener = metadatalistener;
   }

   /**
    * ADVANCED:
    * Return if the session enables concurrent processing.
    * Concurrent processing allow certain processing to be done on seperate threads.
    * This can result in improved performance.
    * This will use the session's server platform's thread pool.
    */
   public boolean isConcurrent() {
       return this.isConcurrent;
   }

   /**
    * ADVANCED:
    * Set if the session enables concurrent processing.
    * Concurrent processing allow certain processing to be done on seperate threads.
    * This can result in improved performance.
    * This will use the session's server platform's thread pool.
    */
   public void setIsConcurrent(boolean isConcurrent) {
       this.isConcurrent = isConcurrent;
   }

   /**
    * ADVANCED:
    * Set to indicate whether ObjectLevelReadQuery should by default use ResultSet Access optimization.
    * If not set then parent's flag is used, is none set then ObjectLevelReadQuery.isResultSetAccessOptimizedQueryDefault is used.
    * If the optimization specified by the session is ignored if incompatible with other query settings.
    */
   public void setShouldOptimizeResultSetAccess(boolean shouldOptimizeResultSetAccess) {
       this.shouldOptimizeResultSetAccess = shouldOptimizeResultSetAccess;
   }

   /**
    * ADVANCED:
    * Indicates whether ObjectLevelReadQuery should by default use ResultSet Access optimization.
    * Optimization specified by the session is ignored if incompatible with other query settings.
    */
   public boolean shouldOptimizeResultSetAccess() {
       return this.shouldOptimizeResultSetAccess;
   }

   /**
    * ADVANCED: Indicates whether an invalid NamedQuery will be tolerated at init time.
    *
    * Default is false.
    */
   public void setTolerateInvalidJPQL(boolean b) {
       this.tolerateInvalidJPQL = b;
   }

   /**
    * ADVANCED: Indicates whether an invalid NamedQuery will be tolerated at init time.
    *
    * Default is false.
    */
   public boolean shouldTolerateInvalidJPQL() {
       return this.tolerateInvalidJPQL;
   }
}
