/*******************************************************************************
 * Copyright (c) 1998, 2016 Oracle and/or its affiliates. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
 * which accompanies this distribution.
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at 
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation from Oracle TopLink
 *     04/01/2011-2.3 Guy Pelletier 
 *       - 337323: Multi-tenant with shared schema support (part 2)
 *     09/09/2011-2.3.1 Guy Pelletier 
 *       - 356197: Add new VPD type to MultitenantType
 *     01/06/2011-2.3 Guy Pelletier 
 *       - 371453: JPA Multi-Tenancy in Bidirectional OneToOne Relation throws ArrayIndexOutOfBoundsException
 ******************************************************************************/  
package org.eclipse.persistence.queries;

import java.util.*;
import java.sql.*;
import org.eclipse.persistence.internal.databaseaccess.*;
import org.eclipse.persistence.internal.identitymaps.CacheId;
import org.eclipse.persistence.internal.indirection.ProxyIndirectionPolicy;
import org.eclipse.persistence.internal.descriptors.*;
import org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism;
import org.eclipse.persistence.internal.sessions.remote.*;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.ResultSetRecord;
import org.eclipse.persistence.internal.sessions.SimpleResultSetRecord;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.sessions.DatabaseRecord;
import org.eclipse.persistence.sessions.SessionProfiler;
import org.eclipse.persistence.sessions.remote.*;
import org.eclipse.persistence.tools.profiler.QueryMonitor;

/**
 * <p><b>Purpose</b>:
 * Concrete class for all read queries involving a single object.
 * <p>
 * <p><b>Responsibilities</b>:
 * Return a single object for the query.
 * Implements the inheritance feature when dealing with abstract descriptors.
 *
 * @author Yvon Lavoie
 * @since TOPLink/Java 1.0
 */
public class ReadObjectQuery extends ObjectLevelReadQuery {
    /** Object that can be used in place of a selection criteria. */
    protected transient Object selectionObject;

    /** Key that can be used in place of a selection criteria. */
    protected Object selectionId;

    /** Can be used to refresh a specific non-cached instance from the database. */
    protected boolean shouldLoadResultIntoSelectionObject = false;    
    
    /**
     * PUBLIC:
     * Return a new read object query.
     * A reference class must be specified before execution.
     * It is better to provide the class and expression builder on construction to esnure a single expression builder is used.
     * If no selection criteria is specified this will reads the first object found in the database.
     */
    public ReadObjectQuery() {
        super();
    }

    /**
     * PUBLIC:
     * Return a new read object query.
     * By default, the query has no selection criteria. Executing this query without
     * selection criteria will always result in a database access to read the first
     * instance of the specified Class found in the database. This is true no
     * matter how cache usage is configured and even if an instance of the
     * specified Class exists in the cache.
     * Executing a query with selection criteria allows you to avoid a database
     * access if the selected instance is in the cache. For this reason, you may whish to use a ReadObjectQuery constructor that takes selection criteria, such as: {@link #ReadObjectQuery(Class, Call)}, {@link #ReadObjectQuery(Class, Expression)}, {@link #ReadObjectQuery(Class, ExpressionBuilder)}, {@link #ReadObjectQuery(ExpressionBuilder)}, {@link #ReadObjectQuery(Object)}, or {@link #ReadObjectQuery(Object, QueryByExamplePolicy)}.
     */
    public ReadObjectQuery(Class classToRead) {
        this();
        this.referenceClass = classToRead;
    }

    /**
     * PUBLIC:
     * Return a new read object query for the class and the selection criteria.
     */
    public ReadObjectQuery(Class classToRead, Expression selectionCriteria) {
        this();
        this.referenceClass = classToRead;
        setSelectionCriteria(selectionCriteria);
    }

    /**
     * PUBLIC:
     * Return a new read object query for the class.
     * The expression builder must be used for all associated expressions used with the query.
     */
    public ReadObjectQuery(Class classToRead, ExpressionBuilder builder) {
        this();
        this.defaultBuilder = builder;
        this.referenceClass = classToRead;
    }

    /**
     * PUBLIC:
     * Return a new read object query.
     * The call represents a database interaction such as SQL, Stored Procedure.
     */
    public ReadObjectQuery(Class classToRead, Call call) {
        this();
        this.referenceClass = classToRead;
        setCall(call);
    }

    /**
     * PUBLIC:
     * Return a new read object query.
     * The call represents a database interaction such as SQL, Stored Procedure.
     */
    public ReadObjectQuery(Call call) {
        this();
        setCall(call);
    }

    /**
     * PUBLIC:
     * Return a query to read the object with the same primary key as the provided object.
     * Note: This is not a query by example object, only the primary key will be used for the selection criteria.
     */
    public ReadObjectQuery(Object objectToRead) {
        this();
        setSelectionObject(objectToRead);
    }

    /**
     * PUBLIC:
     * Return a query by example query to find an object matching the attributes of the example object.
     */
    public ReadObjectQuery(Object exampleObject, QueryByExamplePolicy policy) {
        this();
        setExampleObject(exampleObject);
        setQueryByExamplePolicy(policy);
    }

    /**
     * PUBLIC:
     * The expression builder should be provide on creation to ensure only one is used.
     */
    public ReadObjectQuery(ExpressionBuilder builder) {
        this();
        this.defaultBuilder = builder;
    }

    /**
     * INTERNAL:
     * <P> This method is called by the object builder when building an original.
     * It will cause the original to be cached in the query results if the query
     * is set to do so.
     */
    public void cacheResult(Object object) {
        Object cachableObject = object;
        if (object == null) {
            this.temporaryCachedQueryResults = InvalidObject.instance();
        } else {
            if (this.shouldUseWrapperPolicy) {
                cachableObject = this.session.wrapObject(object);
            }
            this.temporaryCachedQueryResults = cachableObject;
        }
    }


    /**
     * PUBLIC:
     * The cache will be checked only if the query contains exactly the primary key.
     * Queries can be configured to use the cache at several levels.
     * Other caching option are available.
     * @see #setCacheUsage(int)
     */
    public void checkCacheByExactPrimaryKey() {
        setCacheUsage(CheckCacheByExactPrimaryKey);
    }

    /**
     * PUBLIC:
     * This is the default, the cache will be checked only if the query contains the primary key.
     * Queries can be configured to use the cache at several levels.
     * Other caching option are available.
     * @see #setCacheUsage(int)
     */
    public void checkCacheByPrimaryKey() {
        setCacheUsage(CheckCacheByPrimaryKey);
    }

    /**
     * PUBLIC:
     * The cache will be checked completely, then if the object is not found or the query too complex the database will be queried.
     * Queries can be configured to use the cache at several levels.
     * Other caching option are available.
     * @see #setCacheUsage(int)
     */
    public void checkCacheThenDatabase() {
        setCacheUsage(CheckCacheThenDatabase);
    }

    /**
     * INTERNAL:
     * Ensure that the descriptor has been set.
     */
    public void checkDescriptor(AbstractSession session) throws QueryException {
        if (this.descriptor == null) {
            if (getReferenceClass() == null) {
                throw QueryException.referenceClassMissing(this);
            }
            ClassDescriptor referenceDescriptor;
            //Bug#3947714  In case getSelectionObject() is proxy            
            if (getSelectionObject() != null && session.getProject().hasProxyIndirection()) {
                referenceDescriptor = session.getDescriptor(getSelectionObject());            
            } else {
                referenceDescriptor = session.getDescriptor(getReferenceClass());                
            }
            if (referenceDescriptor == null) {
                throw QueryException.descriptorIsMissing(getReferenceClass(), this);
            }
            setDescriptor(referenceDescriptor);
        }
    }

    /**
     * INTERNAL:
     * The cache check is done before the prepare as a hit will not require the work to be done.
     */
    protected Object checkEarlyReturnLocal(AbstractSession session, AbstractRecord translationRow) {
        if (shouldCheckCache() && shouldMaintainCache() && (!shouldRefreshIdentityMapResult() && (!shouldRetrieveBypassCache()))
                && (!(session.isRemoteSession() && (shouldRefreshRemoteIdentityMapResult() || this.descriptor.shouldDisableCacheHitsOnRemote())))
                && (!(shouldCheckDescriptorForCacheUsage() && this.descriptor.shouldDisableCacheHits())) && (!this.descriptor.isDescriptorForInterface())) {
            Object cachedObject = getQueryMechanism().checkCacheForObject(translationRow, session);
            this.isCacheCheckComplete = true;

            // Optimization: If find deleted object by exact primary
            // key expression or selection object/key just abort.
            if (cachedObject == InvalidObject.instance) {
                return cachedObject;
            }
            if (cachedObject != null) {
                if (shouldLoadResultIntoSelectionObject()) {
                    ObjectBuilder builder = this.descriptor.getObjectBuilder();
                    builder.copyInto(cachedObject, getSelectionObject());
                    //put this object into the cache.  This may cause some loss of identity
                    session.getIdentityMapAccessorInstance().putInIdentityMap(getSelectionObject());
                    cachedObject = getSelectionObject();
                }

                // check locking.  If clone has not been locked, do not early return cached object
                if (isLockQuery() && (session.isUnitOfWork() && !((UnitOfWorkImpl)session).isPessimisticLocked(cachedObject))) {
                    return null;
                }
                if (QueryMonitor.shouldMonitor()) {
                    QueryMonitor.incrementReadObjectHits(this);
                }
                session.incrementProfile(SessionProfiler.CacheHits, this);
            } else {
                if (!session.isUnitOfWork()) {
                    if (QueryMonitor.shouldMonitor()) {
                        QueryMonitor.incrementReadObjectMisses(this);
                    }
                    session.incrementProfile(SessionProfiler.CacheMisses, this);
                }
            }
            if (shouldUseWrapperPolicy()) {
                cachedObject = this.descriptor.getObjectBuilder().wrapObject(cachedObject, session);
            }            
            return cachedObject;
        } else {
            if (!session.isUnitOfWork()) {
                if (QueryMonitor.shouldMonitor()) {
                    QueryMonitor.incrementReadObjectMisses(this);
                }
                session.incrementProfile(SessionProfiler.CacheMisses, this);
            }
            return null;
        }
    }

    /**
     * INTERNAL:
     * Check to see if a custom query should be used for this query.
     * This is done before the query is copied and prepared/executed.
     * null means there is none.
     */
    protected DatabaseQuery checkForCustomQuery(AbstractSession session, AbstractRecord translationRow) {
        Boolean useCustomQuery = isCustomQueryUsed;

        checkDescriptor(session);
        if (useCustomQuery == null) {
            // Check if user defined a custom query in the query manager.
            if (!this.isUserDefined) {
                if (!isCallQuery()
                        // By default all descriptors have a custom ("static") read-object query.
                        // This allows the read-object query and SQL to be prepare once.
                        && this.descriptor.getQueryManager().hasReadObjectQuery()) {
                    // If the query require special SQL generation or execution do not use the static read object query.
                    // PERF: the read-object query should always be static to ensure no regeneration of SQL.
                    if ((!hasJoining() || !this.joinedAttributeManager.hasJoinedAttributeExpressions()) && (!hasPartialAttributeExpressions())
                            && (redirector == null) && !doNotRedirect && (!hasAsOfClause()) && (!hasNonDefaultFetchGroup())
                            && (this.shouldUseSerializedObjectPolicy == shouldUseSerializedObjectPolicyDefault)
                            && this.wasDefaultLockMode && (shouldBindAllParameters == null) && (this.hintString == null)) {
                        if ((this.selectionId != null) || (this.selectionObject != null)) {// Must be primary key.
                            useCustomQuery = Boolean.TRUE;
                        } else {
                            Expression selectionCriteria = getSelectionCriteria();
                            if (selectionCriteria != null) {
                                AbstractRecord primaryKeyRow = this.descriptor.getObjectBuilder().extractPrimaryKeyRowFromExpression(selectionCriteria, translationRow, session);
                                // Only execute the query if the selection criteria has the primary key fields set
                                if (primaryKeyRow != null) {
                                    useCustomQuery = Boolean.TRUE;
                                }
                            }
                        }
                    }
                }
            }
        }

        //#436871 - attempt to limit cases for race-condition
        if (useCustomQuery != null && useCustomQuery.booleanValue()) {
            ReadObjectQuery customQuery = this.descriptor.getQueryManager().getReadObjectQuery();
            if (this.accessors != null) {
                customQuery = (ReadObjectQuery) customQuery.clone();
                customQuery.setIsExecutionClone(true);
                customQuery.setAccessors(this.accessors);
            }
            isCustomQueryUsed = useCustomQuery;
            return customQuery;
        }
        isCustomQueryUsed = useCustomQuery;
        return null;
    }

    /**
     * INTERNAL:
     * Conform the result in the UnitOfWork.
     */
    protected Object conformResult(Object result, UnitOfWorkImpl unitOfWork, AbstractRecord databaseRow, boolean buildDirectlyFromRows) {
        // Note that if the object does not conform even though other objects might exist on the database null is returned.
        // Note that new objects is checked before the read is executed so does not have to be re-checked.
        // Must unwrap as the built object is always wrapped.
        // Note the object is unwrapped on the parent which it belongs to, as we
        // do not want to trigger a registration just yet.
        Object clone = null;
        if (buildDirectlyFromRows) {
            clone = buildObject((AbstractRecord)result);
        } else {
            clone = registerIndividualResult(
                    this.descriptor.getObjectBuilder().unwrapObject(result, unitOfWork.getParent()),
                    null, unitOfWork, null, null);
        }
        Expression selectionCriteria = getSelectionCriteria();
        if ((selectionCriteria != null) && (this.selectionId == null) && (this.selectionObject == null)) {
            ExpressionBuilder builder = selectionCriteria.getBuilder();
            builder.setSession(unitOfWork.getRootSession(null));
            builder.setQueryClass(getReferenceClass());
        }

        clone = conformIndividualResult(clone, unitOfWork, databaseRow, selectionCriteria, null);
        if (clone == null) {
            return clone;
        }

        if (shouldUseWrapperPolicy()) {
            return this.descriptor.getObjectBuilder().wrapObject(clone, unitOfWork);
        } else {
            return clone;
        }
    }

    /**
     * PUBLIC:
     * Do not refesh/load into the selection object, this is the default.
     * This property allows for the selection object of the query to be refreshed or put into the TopLink cache.
     * By default on a read or refresh the object in the cache is refreshed and returned or a new object is built from the database,
     * in some cases such as EJB BMP it is desirable to refresh or load into the object passed into the read object query.
     * <p>Note: This forces the selection object into the cache a replaces any existing object that may already be there,
     * this is a strict violation of object identity and other objects can still be refering to the old object.
     */
    public void dontLoadResultIntoSelectionObject() {
        setShouldLoadResultIntoSelectionObject(false);
    }

    /**
     * INTERNAL:
     * Execute the query. If there are cached results return those.
     * This must override the super to support result caching.
     *
     * @param session the session in which the receiver will be executed.
     * @return An object or vector, the result of executing the query.
     * @exception DatabaseException - an error has occurred on the database
     */
    public Object execute(AbstractSession session, AbstractRecord row) throws DatabaseException {
        if (shouldCacheQueryResults()) {
            if (shouldConformResultsInUnitOfWork()) {
                throw QueryException.cannotConformAndCacheQueryResults(this);
            }
            if (isPrepared()) {// only prepared queries can have cached results.
                Object result = getQueryResults(session, row, true);
                // Bug6138532 - if result is "cached no results", return null immediately
                if (result == InvalidObject.instance) {
                    return null;
                }
                if (result != null) {
                    if (session.isUnitOfWork()) {
                        result = ((UnitOfWorkImpl)session).registerExistingObject(result);
                    }
                    return result;
                }
            }
        }
        return super.execute(session, row);
    }

    /**
     * INTERNAL:
     * Execute the query.
     * Do a cache lookup and build object from row if required.
     * @exception  DatabaseException - an error has occurred on the database
     * @return object - the first object found or null if none.
     */
    protected Object executeObjectLevelReadQuery() throws DatabaseException {
        if (this.descriptor.isDescriptorForInterface()  || this.descriptor.hasTablePerClassPolicy()) {
            Object returnValue = this.descriptor.getInterfacePolicy().selectOneObjectUsingMultipleTableSubclassRead(this);
            
            if (this.descriptor.hasTablePerClassPolicy() && (!this.descriptor.isAbstract()) && (returnValue == null)) {
                // let it fall through to query the root.
            } else {
                this.executionTime = System.currentTimeMillis();
                return returnValue;
            }
        }
        
        boolean shouldSetRowsForJoins = hasJoining() && this.joinedAttributeManager.isToManyJoin();
        AbstractSession session = getSession();
        Object result = null;
        AbstractRecord row = null;
        
        Object sopObject = getTranslationRow().getSopObject();
        boolean useOptimization = false;
        if (sopObject == null) {
            useOptimization = usesResultSetAccessOptimization(); 
        }        
        
        if (useOptimization) {
            DatabaseCall call = ((DatasourceCallQueryMechanism)this.queryMechanism).selectResultSet();
            this.executionTime = System.currentTimeMillis();
            boolean exceptionOccured = false;
            ResultSet resultSet = call.getResult();
            DatabaseAccessor dbAccessor = (DatabaseAccessor)getAccessor();
            try {
                if (resultSet.next()) {
                    ResultSetMetaData metaData = call.getResult().getMetaData();
                    boolean useSimple = this.descriptor.getObjectBuilder().isSimple(); 
                    DatabasePlatform platform = dbAccessor.getPlatform();
                    boolean optimizeData = platform.shouldOptimizeDataConversion();
                    if (useSimple) {
                        row = new SimpleResultSetRecord(call.getFields(), call.getFieldsArray(), resultSet, metaData, dbAccessor, getExecutionSession(), platform, optimizeData);
                        if (this.descriptor.isDescriptorTypeAggregate()) {
                            // Aggregate Collection may have an unmapped primary key referencing the owner, the corresponding field will not be used when the object is populated and therefore may not be cleared.
                            ((SimpleResultSetRecord)row).setShouldKeepValues(true);
                        }
                    } else {
                        row = new ResultSetRecord(call.getFields(), call.getFieldsArray(), resultSet, metaData, dbAccessor, getExecutionSession(), platform, optimizeData);
                    }
                    if (session.isUnitOfWork()) {
                        result = registerResultInUnitOfWork(row, (UnitOfWorkImpl)session, this.translationRow, true);
                    } else {
                        result = buildObject(row);
                    }
                        
                    if (!useSimple && this.descriptor.getObjectBuilder().shouldKeepRow()) {
                        if (((ResultSetRecord)row).hasResultSet()) {
                        	// ResultSet has not been fully triggered - that means the cached object was used. 
                        	// Yet the row still may be cached in a value holder (see loadBatchReadAttributes and loadJoinedAttributes methods).
                        	// Remove ResultSet to avoid attempt to trigger it (already closed) when pk or fk values (already extracted) accessed when the value holder is instantiated.
                            ((ResultSetRecord)row).removeResultSet();
                        } else {
                            ((ResultSetRecord)row).removeNonIndirectionValues();
                        }
                    }
                }
            } catch (SQLException exception) {
                exceptionOccured = true;
                DatabaseException commException = dbAccessor.processExceptionForCommError(session, exception, call);
                if (commException != null) {
                    throw commException;
                }
                throw DatabaseException.sqlException(exception, call, getAccessor(), session, false);
            } finally {
                try {
                    if (resultSet != null) {
                        resultSet.close();
                    }
                    if (dbAccessor != null) {
                        if (call.getStatement() != null) {
                            dbAccessor.releaseStatement(call.getStatement(), call.getSQLString(), call, session);
                        }
                    }
                    if (call.hasAllocatedConnection()) {
                        getExecutionSession().releaseConnectionAfterCall(this);
                    }
                } catch (RuntimeException cleanupException) {
                    if (!exceptionOccured) {
                        throw cleanupException;
                    }
                } catch (SQLException cleanupSQLException) {
                    if (!exceptionOccured) {
                        throw DatabaseException.sqlException(cleanupSQLException, call, dbAccessor, session, false);
                    }
                }
            }
        } else {
            if (sopObject != null) {
                row = new DatabaseRecord(0);
                row.setSopObject(sopObject);
            } else {
                // If using 1-m joins, must select all rows.
                if (shouldSetRowsForJoins) {
                    List rows = getQueryMechanism().selectAllRows();
                    if (rows.size() > 0) {
                        row = (AbstractRecord)rows.get(0);
                    }
                    getJoinedAttributeManager().setDataResults(rows, session);
                } else {
                    row = getQueryMechanism().selectOneRow();
                }
            }
            
            this.executionTime = System.currentTimeMillis();
            if (row != null) {
                if (session.isUnitOfWork()) {
                    result = registerResultInUnitOfWork(row, (UnitOfWorkImpl)session, this.translationRow, true);
                } else {
                    result = buildObject(row);
                }
                if (sopObject != null) {
                	// remove sopObject so it's not stuck in a value holder.
                    row.setSopObject(null);
                }
            }
        }
        if ((result == null) && shouldCacheQueryResults()) {
            cacheResult(null);
        }
        if ((result == null) && this.shouldRefreshIdentityMapResult) {
            // bug5955326, should invalidate the shared cached if refreshed object no longer exists.
            if (this.selectionId != null) {
                session.getParentIdentityMapSession(this.descriptor, true, true).getIdentityMapAccessor().invalidateObject(this.selectionId, this.referenceClass);
            } else if (this.selectionObject != null) {
                session.getParentIdentityMapSession(this.descriptor, true, true).getIdentityMapAccessor().invalidateObject(this.selectionObject);
            }
        }                

        if (this.shouldIncludeData && (sopObject == null)) {
            ComplexQueryResult complexResult = new ComplexQueryResult();
            complexResult.setResult(result);
            complexResult.setData(row);
            return complexResult;
        }

        return result;
    }
    
    /**
     * INTERNAL:
     * Execute the query building the objects directly from the database result-set.
     * @exception  DatabaseException - an error has occurred on the database
     * @return object - the first object found or null if none.
     */
    protected Object executeObjectLevelReadQueryFromResultSet() throws DatabaseException {
        AbstractSession session = this.session;
        DatabasePlatform platform = session.getPlatform();
        DatabaseCall call = ((DatasourceCallQueryMechanism)this.queryMechanism).selectResultSet();
        Statement statement = call.getStatement();
        ResultSet resultSet = call.getResult();
        DatabaseAccessor accessor = (DatabaseAccessor)((List<Accessor>)this.accessors).get(0);
        boolean exceptionOccured = false;
        try {
            if (!resultSet.next()) {
                return null;
            }
            ResultSetMetaData metaData = resultSet.getMetaData();
            return this.descriptor.getObjectBuilder().buildObjectFromResultSet(this, null, resultSet, session, accessor, metaData, platform, call.getFields(), call.getFieldsArray());
        } catch (SQLException exception) {
            exceptionOccured = true;
            DatabaseException commException = accessor.processExceptionForCommError(session, exception, call);
            if (commException != null) {
                throw commException;
            }
            throw DatabaseException.sqlException(exception, call, accessor, session, false);
        } finally {
            try {
                if (resultSet != null) {
                    resultSet.close();
                }
                if (statement != null) {
                    accessor.releaseStatement(statement, call.getSQLString(), call, session);
                }
                if (accessor != null) {
                    session.releaseReadConnection(accessor);
                }
            } catch (SQLException exception) {
                if (!exceptionOccured) {
                    //in the case of an external connection pool the connection may be null after the statement release
                    // if it is null we will be unable to check the connection for a comm error and
                    //therefore must return as if it was not a comm error.
                    DatabaseException commException = accessor.processExceptionForCommError(session, exception, call);
                    if (commException != null) {
                        throw commException;
                    }
                    throw DatabaseException.sqlException(exception, call, accessor, session, false);
                }
            }
        }
    }

    /**
     * INTERNAL:
     * Extract the correct query result from the transporter.
     */
    public Object extractRemoteResult(Transporter transporter) {
        return ((DistributedSession)getSession()).getObjectCorrespondingTo(transporter.getObject(), transporter.getObjectDescriptors(), new IdentityHashMap(), this);
    }

    /**
     * INTERNAL:
     * Returns the specific default redirector for this query type.  There are numerous default query redirectors.
     * See ClassDescriptor for their types.
     */
    protected QueryRedirector getDefaultRedirector(){
        return descriptor.getDefaultReadObjectQueryRedirector();
    }

    /**
     * PUBLIC:
     * The primary key can be specified if used instead of an expression or selection object.
     * If composite the primary must be in the same order as defined in the descriptor.
     * @Depreacted since EclipseLink 2.1, replaced by getSelectionId()
     * @see #getSelectionId()
     */
    @Deprecated
    public Vector getSelectionKey() {
        if (this.selectionId instanceof CacheId) {
            return new Vector(Arrays.asList(((CacheId)this.selectionId).getPrimaryKey()));
        }
        Vector primaryKey = new Vector(1);
        primaryKey.add(this.selectionId);
        return (Vector)selectionId;

    }

    /**
     * PUBLIC:
     * Return the selection object of the query.
     * This can be used instead of a where clause expression for single object primary key queries.
     * The selection object given should have a primary key defined,
     * this primary key will be used to query the database instance of the same object.
     * This is a basic form of query by example where only the primary key is required,
     * it can be used for simple query forms, or testing.
     */
    public Object getSelectionObject() {
        return selectionObject;
    }

    /**
     * PUBLIC:
     * Return if this is a read object query.
     */
    public boolean isReadObjectQuery() {
        return true;
    }

    /**
     * INTERNAL:
     * Return if the query is by primary key.
     */
    public boolean isPrimaryKeyQuery() {
        return (this.selectionId != null) || (this.selectionObject != null);
    }

    /**
     * PUBLIC:
     * Allow for the selection object of the query to be refreshed or put into the EclipseLink cache.
     * By default on a read or refresh the object in the cache is refreshed and returned or a new object is built from the database,
     * in some cases such as EJB BMP it is desirable to refresh or load into the object passed into the read object query.
     * <p>Note: This forces the selection object into the cache a replaces any existing object that may already be there,
     * this is a strict violation of object identity and other objects can still be referring to the old object.
     */
    public void loadResultIntoSelectionObject() {
        setShouldLoadResultIntoSelectionObject(true);
    }
    
    /**
     * INTERNAL:
     * Copy all setting from the query.
     * This is used to morph queries from one type to the other.
     * By default this calls prepareFromQuery, but additional properties may be required
     * to be copied as prepareFromQuery only copies properties that affect the SQL.
     */
    public void copyFromQuery(DatabaseQuery query) {
        super.copyFromQuery(query);
        if (query.isReadObjectQuery()) {
            ReadObjectQuery readQuery = (ReadObjectQuery)query;
            this.selectionId = readQuery.selectionId;
            this.selectionObject = readQuery.selectionObject;
            this.shouldLoadResultIntoSelectionObject = readQuery.shouldLoadResultIntoSelectionObject;
        }
    }
    
    /**
     * INTERNAL:
     * Prepare the receiver for execution in a session.
     */
    protected void prepare() throws QueryException {
        if (prepareFromCachedQuery()) {
            return;
        }
        super.prepare();
        
        if ((this.selectionId != null) || (this.selectionObject != null)) {
            // The expression is set in the prepare as params.
            setSelectionCriteria(this.descriptor.getObjectBuilder().getPrimaryKeyExpression());
            setExpressionBuilder(getSelectionCriteria().getBuilder());
            extendPessimisticLockScope();
            // For bug 2989998 the translation row is required to be set at this point.
            if (!shouldPrepare()) {
                if (this.selectionId != null) {
                    // Row must come from the key.
                    setTranslationRow(this.descriptor.getObjectBuilder().buildRowFromPrimaryKeyValues(this.selectionId, this.session));
                } else {//(getSelectionObject() != null)
                    setTranslationRow(this.descriptor.getObjectBuilder().buildRowForTranslation(this.selectionObject, this.session));
                }
            }
        }

        if (this.descriptor.isDescriptorForInterface()) {
            return;
        }
        
        // PERF: Disable cache check if not a primary key query.
        if (isExpressionQuery()) {
            Expression selectionCriteria = getSelectionCriteria();
            if (selectionCriteria != null) {
                if (((this.cacheUsage == CheckCacheByPrimaryKey)
                                && (!this.descriptor.getObjectBuilder().isPrimaryKeyExpression(false, selectionCriteria, this.session)))
                        || ((this.cacheUsage == CheckCacheByExactPrimaryKey)
                                && (!this.descriptor.getObjectBuilder().isPrimaryKeyExpression(true, selectionCriteria, this.session)))) {
                    this.cacheUsage = DoNotCheckCache;
                }
            }
        }
        
        // If using 1-m joining select all rows.
        if ((this.joinedAttributeManager != null) && this.joinedAttributeManager.isToManyJoin()) {
            getQueryMechanism().prepareSelectAllRows();
        } else {
            getQueryMechanism().prepareSelectOneRow();
        }

        // should be called after prepareSelectRow so that the call knows whether it returns ResultSet
        prepareResultSetAccessOptimization();
    }
    
    /**
     * INTERNAL:
     * Set the properties needed to be cascaded into the custom query including the translation row.
     * This is used only for primary key queries, as the descriptor query manager
     * stores a predefined query for this query to avoid having to re-prepare and allow for customization.
     */
    protected void prepareCustomQuery(DatabaseQuery customQuery) {
        super.prepareCustomQuery(customQuery);
        ReadObjectQuery customReadQuery = (ReadObjectQuery)customQuery;
        customReadQuery.shouldRefreshIdentityMapResult = this.shouldRefreshIdentityMapResult;
        customReadQuery.cascadePolicy = this.cascadePolicy;
        customReadQuery.shouldMaintainCache = this.shouldMaintainCache;
        customReadQuery.shouldUseWrapperPolicy = this.shouldUseWrapperPolicy;
        // CR... was missing some values, execution could cause infinite loop.
        customReadQuery.queryId = this.queryId;
        customReadQuery.executionTime = this.executionTime;
        customReadQuery.shouldLoadResultIntoSelectionObject = this.shouldLoadResultIntoSelectionObject;
        AbstractRecord primaryKeyRow;
        if (this.selectionObject != null) {
            // CR#... Must also set the selection object as may be loading into the object (refresh)
            customReadQuery.selectionObject = this.selectionObject;
            // The translation/primary key row will be set in prepareForExecution.
        } else if (this.selectionId != null) {
            customReadQuery.selectionId = this.selectionId;
        } else {
            // The primary key row must be used.
            primaryKeyRow = customQuery.getDescriptor().getObjectBuilder().extractPrimaryKeyRowFromExpression(getSelectionCriteria(), customQuery.getTranslationRow(), customReadQuery.getSession());
            customReadQuery.setTranslationRow(primaryKeyRow);
        }
    }

    /**
     * INTERNAL:
     * Prepare the receiver for execution in a session.
     */
    public void prepareForExecution() throws QueryException {
        super.prepareForExecution();

        // For bug 2989998 the translation row now sometimes set earlier in prepare.
        if (shouldPrepare()) {
            if (this.selectionId != null) {
                // Row must come from the key.
                this.translationRow = this.descriptor.getObjectBuilder().buildRowFromPrimaryKeyValues(this.selectionId, getSession());
            } else if (this.selectionObject != null) {
                // The expression is set in the prepare as params.
                this.translationRow = this.descriptor.getObjectBuilder().buildRowForTranslation(this.selectionObject, getSession());
            }
        }
        
        // If we have tenant discriminator fields we need to add them to the 
        // database row when doing a primary key query.
        // Modifying the translation row here will modify it on the original 
        // query which is not good (will append the tenant field to the sql call 
        // for subsequent queries) The translation row must be cloned to isolate 
        // this.
        if (getDescriptor().hasMultitenantPolicy()) {
            this.translationRow = this.translationRow.clone();
            getDescriptor().getMultitenantPolicy().addFieldsToRow(this.translationRow, getSession());            
        }
    }

    /**
     * INTERNAL:
     * Prepare the receiver for execution in a session.
     */
    protected void prePrepare() throws QueryException {
        super.prePrepare();
        //Bug#3947714  In case getSelectionObject() is proxy            
        if (getSelectionObject() != null && getSession().getProject().hasProxyIndirection()) {
            setSelectionObject(ProxyIndirectionPolicy.getValueFromProxy(getSelectionObject()));
        }
    }

    /**
     * INTERNAL:
     * All objects queried via a UnitOfWork get registered here.  If the query
     * went to the database.
     * <p>
     * Involves registering the query result individually and in totality, and
     * hence refreshing / conforming is done here.
     * @param result may be collection (read all) or an object (read one),
     * or even a cursor.  If in transaction the shared cache will
     * be bypassed, meaning the result may not be originals from the parent
     * but raw database rows.
     * @param unitOfWork the unitOfWork the result is being registered in.
     * @param arguments the original arguments/parameters passed to the query
     * execution.  Used by conforming
     * @param buildDirectlyFromRows If in transaction must construct
     * a registered result from raw database rows.
     * @return the final (conformed, refreshed, wrapped) UnitOfWork query result
     */
    public Object registerResultInUnitOfWork(Object result, UnitOfWorkImpl unitOfWork, AbstractRecord arguments, boolean buildDirectlyFromRows) {
        if (result == null) {
            return null;
        }
        if (unitOfWork.hasCloneMapping() // PERF: Avoid conforming empty uow.
                && (shouldConformResultsInUnitOfWork() || this.descriptor.shouldAlwaysConformResultsInUnitOfWork())) {
            return conformResult(result, unitOfWork, arguments, buildDirectlyFromRows);
        }
        Object clone = null;
        if (buildDirectlyFromRows) {
            clone = buildObject((AbstractRecord)result);
        } else {
            clone = registerIndividualResult(result, null, unitOfWork, null, null);
        }

        if (shouldUseWrapperPolicy()) {
            clone = this.descriptor.getObjectBuilder().wrapObject(clone, unitOfWork);
        }
        return clone;
    }

    protected Object remoteExecute() {
        // Do a cache lookup.
        checkDescriptor(session);
        // As the selection object is transient, compute the key.
        if (getSelectionObject() != null) {
            // Must be checked separately as the expression and row is not yet set.
            setSelectionId(getDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(getSelectionObject(), session));
        }

        Object cacheHit = checkEarlyReturn(getSession(), getTranslationRow());
        if ((cacheHit != null) || shouldCheckCacheOnly()) {
            if (cacheHit == InvalidObject.instance) {
                return null;
            }
            return cacheHit;
        }

        return super.remoteExecute();
    }

    /**
     * INTERNAL:
     * replace the value holders in the specified result object(s)
     */
    public Map replaceValueHoldersIn(Object object, RemoteSessionController controller) {
        return controller.replaceValueHoldersIn(object);
    }

    /**
     * INTERNAL:
     * Return the primary key stored in this query 
     * 
     * @return the selection id of this ReadObjectQuery
     */
    @Override
    protected Object getQueryPrimaryKey(){
        return getSelectionId();
    }
    
    /**
     * PUBLIC:
     * Return Id of the object to be selected by the query.
     */
    public Object getSelectionId() {
        return this.selectionId;
    }

    /**
     * PUBLIC:
     * The Id of the object to be selected by the query.
     * This will generate a query by primary key.
     * This can be used instead of an Expression, SQL, or JPQL, or example object.
     * The Id is the Id value for a singleton primary key,
     * for a composite it is an instance of CacheId.
     * @see CacheId
     */
    public void setSelectionId(Object id) {
        this.selectionId = id;
    }

    /**
     * PUBLIC:
     * The primary key can be specified if used instead of an expression or selection object.
     * If composite the primary must be in the same order as defined in the descriptor.
     * @depreacted since EclipseLink 2.1, replaced by setSelectionId(Object)
     * @see #setSelectionId(Object)
     */
    @Deprecated
    public void setSelectionKey(List selectionKey) {
        if (selectionKey == null) {
            this.selectionId = null;
        } else if (selectionKey.size() == 1) {
            this.selectionId = selectionKey.get(0);            
        } else {
            this.selectionId = new CacheId(selectionKey.toArray());
        }
    }

    /**
     * PUBLIC:
     * Used to set the where clause of the query.
     * This can be used instead of a where clause expression for single object primary key queries.
     * The selection object given should have a primary key defined,
     * this primary key will be used to query the database instance of the same object.
     * This is a basic form of query by example where only the primary key is required,
     * it can be used for simple query forms, or testing.
     */
    public void setSelectionObject(Object selectionObject) {
        if (selectionObject == null) {
            throw QueryException.selectionObjectCannotBeNull(this);
        }
        setSelectionId(null);
        // Check if the query needs to be unprepared.
        if ((this.selectionObject == null) || (this.selectionObject.getClass() != selectionObject.getClass())) {
            setIsPrepared(false);
        }
        setReferenceClass(selectionObject.getClass());
        this.selectionObject = selectionObject;
    }

    /**
     * PUBLIC:
     * Allow for the selection object of the query to be refreshed or put into the EclipseLink cache.
     * By default on a read or refresh the object in the cache is refreshed and returned or a new object is built from the database,
     * in some cases such as EJB BMP it is desirable to refresh or load into the object passed into the read object query.
     * <p>Note: This forces the selection object into the cache a replaces any existing object that may already be there,
     * this is a strict violation of object identity and other objects can still be referring to the old object.
     */
    public void setShouldLoadResultIntoSelectionObject(boolean shouldLoadResultIntoSelectionObject) {
        this.shouldLoadResultIntoSelectionObject = shouldLoadResultIntoSelectionObject;
    }

    /**
     * PUBLIC:
     * The primary key can be specified if used instead of an expression or selection object.
     * @Depreacted since EclipseLink 2.1, replaced by setSelectionId(Object)
     * @see #setSelectionId(Object)
     */
    @Deprecated
    public void setSingletonSelectionKey(Object selectionKey) {
        Vector key = new NonSynchronizedVector();
        key.add(selectionKey);
        setSelectionKey(key);
    }

    /**
     * PUBLIC:
     * Return if cache should be checked.
     */
    public boolean shouldCheckCacheByExactPrimaryKey() {
        return this.cacheUsage == CheckCacheByExactPrimaryKey;
    }

    /**
     * PUBLIC:
     * Return if cache should be checked.
     */
    public boolean shouldCheckCacheByPrimaryKey() {
        return (this.cacheUsage == CheckCacheByPrimaryKey) || (this.cacheUsage == UseDescriptorSetting);
    }

    /**
     * PUBLIC:
     * Return if cache should be checked.
     */
    public boolean shouldCheckCacheThenDatabase() {
        return this.cacheUsage == CheckCacheThenDatabase;
    }

    /**
     * PUBLIC:
     * return true if the result should be loaded into the passed in selection Object
     */
    public boolean shouldLoadResultIntoSelectionObject() {
        return shouldLoadResultIntoSelectionObject;
    }

    /**
     * INTERNAL:
     * Return if the query has an non-default fetch group defined for itself.
     */
    protected boolean hasNonDefaultFetchGroup() {
        return this.descriptor.hasFetchGroupManager() && ((this.fetchGroup != null) || (this.fetchGroupName != null)
                || (!this.shouldUseDefaultFetchGroup && (this.descriptor.getFetchGroupManager().getDefaultFetchGroup() != null)));

    }
}
