/*
 * Copyright (c) 1998, 2021 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 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
//     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
package org.eclipse.persistence.queries;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.expressions.ExpressionBuilder;
import org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor;
import org.eclipse.persistence.internal.databaseaccess.DatabaseCall;
import org.eclipse.persistence.internal.databaseaccess.DatabasePlatform;
import org.eclipse.persistence.internal.descriptors.ObjectBuilder;
import org.eclipse.persistence.internal.expressions.QueryKeyExpression;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.InvalidObject;
import org.eclipse.persistence.internal.helper.ThreadCursoredList;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism;
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.sessions.remote.RemoteSessionController;
import org.eclipse.persistence.internal.sessions.remote.Transporter;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.OneToManyMapping;
import org.eclipse.persistence.sessions.DatabaseRecord;
import org.eclipse.persistence.sessions.SessionProfiler;
import org.eclipse.persistence.sessions.remote.DistributedSession;
import org.eclipse.persistence.tools.profiler.QueryMonitor;

/**
 * <p><b>Purpose</b>:
 * Concrete class for all read queries involving a collection of objects.
 *
 * <p><b>Responsibilities</b>:
 * Return a container of the objects generated by the query.
 * Implements the inheritance feature when dealing with abstract descriptors
 *
 * @author Yvon Lavoie
 * @since TOPLink/Java 1.0
 */
public class ReadAllQuery extends ObjectLevelReadQuery {
    /** Used for collection and stream support. */
    protected ContainerPolicy containerPolicy;

    /** Used for Oracle HierarchicalQuery support */
    protected Expression startWithExpression;
    protected Expression connectByExpression;
    protected List<Expression> orderSiblingsByExpressions;
    protected Direction direction;

    /**
     * Specifies the direction in which the hierarchy is traversed in a
     * hierarchical query.
     */
    public static enum Direction {
        /**
         * Hierarchy will be traversed from parent to child - PRIOR keyword is
         * generated on the left side of the equation
         */
        PARENT_TO_CHILD,
        /**
         * Hierarchy will be traversed from child to parent - PRIOR keyword is
         * generated on the right side of the equation
         */
        CHILD_TO_PARENT;

        /**
         * PUBLIC: Returns the default hierarchy traversal direction for the
         * specified mapping.<br>
         * For OneToOne mappings, source in parent object goes to target in
         * child object, collections are the opposite way.
         *
         * @param mapping
         *            The mapping for which to return default hierarchy
         *            traversal direction
         * @return The default hierarchy traversal direction for the mapping
         *         passed
         */
        public static Direction getDefault(DatabaseMapping mapping) {
            return mapping != null && mapping.isOneToOneMapping() ? CHILD_TO_PARENT : PARENT_TO_CHILD;
        }
    }

    /**
     * PUBLIC:
     * Return a new read all query.
     * A reference class must be specified before execution.
     * It is better to provide the class and expression builder on construction to ensure a single expression builder is used.
     * If no selection criteria is specified this will read all objects of the class from the database.
     */
    public ReadAllQuery() {
        super();
        setContainerPolicy(ContainerPolicy.buildDefaultPolicy());
    }

    /**
     * PUBLIC:
     * Return a new read all query.
     * It is better to provide the class and expression builder on construction to ensure a single expression builder is used.
     * If no selection criteria is specified this will read all objects of the class from the database.
     */
    public ReadAllQuery(Class classToRead) {
        this();
        this.referenceClass = classToRead;
    }

    /**
     * PUBLIC:
     * Return a new read all query for the class and the selection criteria.
     */
    public ReadAllQuery(Class classToRead, Expression selectionCriteria) {
        this();
        this.referenceClass = classToRead;
        setSelectionCriteria(selectionCriteria);
    }

    /**
     * PUBLIC:
     * Return a new read all query for the class.
     * The expression builder must be used for all associated expressions used with the query.
     */
    public ReadAllQuery(Class classToRead, ExpressionBuilder builder) {
        this();
        this.defaultBuilder = builder;
        this.referenceClass = classToRead;
    }

    /**
     * PUBLIC:
     * Return a new read all query.
     * The call represents a database interaction such as SQL, Stored Procedure.
     */
    public ReadAllQuery(Class classToRead, Call call) {
        this();
        this.referenceClass = classToRead;
        setCall(call);
    }

    /**
     * PUBLIC:
     * Return a query by example query to find all objects matching the attributes of the example object.
     */
    public ReadAllQuery(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 ReadAllQuery(ExpressionBuilder builder) {
        this();
        this.defaultBuilder = builder;
    }

    /**
     * PUBLIC:
     * Create a read all query with the database call.
     */
    public ReadAllQuery(Call call) {
        this();
        setCall(call);
    }

    /**
     * PUBLIC:
     * Order the query results by the object's attribute or query key name.
     */
    public void addAscendingOrdering(String queryKeyName) {
        addOrdering(getExpressionBuilder().get(queryKeyName).ascending());
    }

    /**
     * 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.
     */
    @Override
    public void cacheResult(Object unwrappedOriginal) {
        Collection container = (Collection)getTemporaryCachedQueryResults();
        if (container == null) {
            container = (Collection)getContainerPolicy().containerInstance();
            setTemporaryCachedQueryResults(container);
        }
        getContainerPolicy().addInto(unwrappedOriginal, container, getSession());
    }

    /**
     * INTERNAL:
     * The cache check is done before the prepare as a hit will not require the work to be done.
     */
    @Override
    protected Object checkEarlyReturnLocal(AbstractSession session, AbstractRecord translationRow) {
        // Check for in-memory only query.
        if (shouldCheckCacheOnly()) {
            // assert !isReportQuery();
            if (shouldUseWrapperPolicy()) {
                getContainerPolicy().setElementDescriptor(this.descriptor);
            }

            // PERF: Fixed to not query each unit of work cache (is not conforming),
            // avoid hashtable and primary key indexing.
            // At some point we may need to support some kind of in-memory with conforming option,
            // but we do not currently allow this.
            AbstractSession rootSession = session;
            while (rootSession.isUnitOfWork()) {
                rootSession = rootSession.getParent();
            }
            Vector allCachedVector = rootSession.getIdentityMapAccessor().getAllFromIdentityMap(getSelectionCriteria(), getReferenceClass(), translationRow, getInMemoryQueryIndirectionPolicyState(), false);

            // Must ensure that all of the objects returned are correctly registered in the unit of work.
            if (session.isUnitOfWork()) {
                allCachedVector = ((UnitOfWorkImpl)session).registerAllObjects(allCachedVector);
            }

            this.isCacheCheckComplete = true;

            return getContainerPolicy().buildContainerFromVector(allCachedVector, session);
        } else {
            return null;
        }
    }

    /**
     * INTERNAL:
     * Check and return custom query flag. Custom query flag value is initialized when stored value is {@code null}.
     * Called from {@link #checkForCustomQuery(AbstractSession, AbstractRecord)} to retrieve custom query flag.
     * @param session        Current session (not used).
     * @param translationRow Database record (not used).
     * @return Current custom query flag. Value will never be {@code null}.
     */
    @Override
    protected Boolean checkCustomQueryFlag(final AbstractSession session, final AbstractRecord translationRow) {
        // #436871 - Use local copy to avoid NPE from concurrent modification.
        final Boolean useCustomQuery = isCustomQueryUsed;
        if (useCustomQuery != null) {
            return useCustomQuery;
        // Initialize custom query flag.
        } else {
            final boolean useCustomQueryValue =
                    !isUserDefined() && isExpressionQuery() && getSelectionCriteria() == null
                    && isDefaultPropertiesQuery() && (!hasOrderByExpressions())
                    && descriptor.getQueryManager().hasReadAllQuery();
            setIsCustomQueryUsed(useCustomQueryValue);
            return useCustomQueryValue;
        }
    }

    /**
     * INTERNAL:
     * Get custom all read query from query manager.
     * Called from {@link #checkForCustomQuery(AbstractSession, AbstractRecord)} to retrieve custom read query.
     * @return Custom all read query from query manager.
     */
    @Override
    protected ObjectLevelReadQuery getReadQuery() {
        return descriptor.getQueryManager().getReadAllQuery();
    }

    /**
     * INTERNAL:
     * Creates and returns a copy of this query.
     * @return A clone of this instance.
     */
    @Override
    public Object clone() {
        final ReadAllQuery cloneQuery = (ReadAllQuery)super.clone();
        // Don't use setters as that will trigger unprepare.
        cloneQuery.containerPolicy = containerPolicy.clone(cloneQuery);
        return cloneQuery;
    }

    /**
     * INTERNAL:
     * Conform the result if specified.
     */
    protected Object conformResult(Object result, UnitOfWorkImpl unitOfWork, AbstractRecord arguments, boolean buildDirectlyFromRows) {
        Expression selectionCriteria = getSelectionCriteria();
        if (selectionCriteria != null) {
            ExpressionBuilder builder = getSelectionCriteria().getBuilder();
            builder.setSession(unitOfWork.getRootSession(null));
            builder.setQueryClass(getReferenceClass());
            if (getQueryMechanism().isExpressionQueryMechanism() && selectionCriteria.isLogicalExpression()) {
                // bug #526546
                if (builder.derivedExpressions != null) {
                    for (Expression e : builder.derivedExpressions) {
                        if (e.isQueryKeyExpression() && ((QueryKeyExpression) e).shouldQueryToManyRelationship()) {
                            DatabaseMapping mapping = ((QueryKeyExpression) e).getMapping();
                            if (mapping.isOneToManyMapping()) {
                                OneToManyMapping otm = (OneToManyMapping) mapping;
                                Expression join = otm.buildSelectionCriteria();
                                selectionCriteria = selectionCriteria.and(join);
                            }
                        }
                    }
                }
            }

        }

        // If the query is redirected then the collection returned might no longer
        // correspond to the original container policy.  CR#2342-S.M.
        ContainerPolicy cp;
        if (getRedirector() != null) {
            cp = ContainerPolicy.buildPolicyFor(result.getClass());
        } else {
            cp = getContainerPolicy();
        }

        // This code is now a great deal different...  For one, registration is done
        // as part of conforming.  Also, this should only be called if one actually
        // is conforming.
        // First scan the UnitOfWork for conforming instances.
        // This will walk through the entire cache of registered objects.
        // Let p be objects from result not in the cache.
        // Let c be objects from cache.
        // Presently p intersect c = empty set, but later p subset c.
        // By checking cache now doesConform will be called p fewer times.
        Map<Object, Object> indexedInterimResult = unitOfWork.scanForConformingInstances(selectionCriteria, getReferenceClass(), arguments, this);

        Cursor cursor = null;
        // In the case of cursors just conform/register the initially read collection.
        if (cp.isCursorPolicy()) {
            cursor = (Cursor)result;
            cp = ContainerPolicy.buildPolicyFor(ClassConstants.Vector_class);
            // In nested UnitOfWork session might have been session of the parent.
            cursor.setSession(unitOfWork);
            result = cursor.getObjectCollection();
            // for later incremental conforming...
            cursor.setInitiallyConformingIndex(indexedInterimResult);
            cursor.setSelectionCriteriaClone(getSelectionCriteria());
            cursor.setTranslationRow(arguments);
        }

        // Now conform the result from the database.
        // Remove any deleted or changed objects that no longer conform.
        // Deletes will only work for simple queries, queries with or's or anyof's may not return
        // correct results when untriggered indirection is in the model.
        List fromDatabase = null;

        // When building directly from rows, one of the performance benefits
        // is that we no longer have to wrap and then unwrap the originals.
        // result is just a vector, not a container of wrapped originals.
        if (buildDirectlyFromRows) {
            List<AbstractRecord> rows = (List<AbstractRecord>)result;
            int size = rows.size();
            fromDatabase = new ArrayList(size);
            for (int index = 0; index < size; index++) {
                AbstractRecord row = rows.get(index);
                // null is placed in the row collection for 1-m joining to filter duplicate rows.
                if (row != null) {
                    Object clone = conformIndividualResult(buildObject(row), unitOfWork, arguments, getSelectionCriteria(), indexedInterimResult);
                    if (clone != null) {
                        fromDatabase.add(clone);
                    }
                }
            }
        } else {
            fromDatabase = new ArrayList(cp.sizeFor(result));
            AbstractSession sessionToUse = unitOfWork.getParent();
            for (Object iter = cp.iteratorFor(result); cp.hasNext(iter);) {
                Object object = cp.next(iter, sessionToUse);
                Object clone = conformIndividualResult(registerIndividualResult(object, null, unitOfWork, null, null), unitOfWork, arguments, getSelectionCriteria(), indexedInterimResult);
                if (clone != null) {
                    fromDatabase.add(clone);
                }
            }
        }

        // Now add the unwrapped conforming instances into an appropriate container.
        // Wrapping is done automatically.
        // Make sure a vector of exactly the right size is returned.
        Object conformedResult = cp.containerInstance(indexedInterimResult.size() + fromDatabase.size());
        for (Iterator<Object> enumtr = indexedInterimResult.values().iterator(); enumtr.hasNext();) {
            Object eachClone = enumtr.next();
            cp.addInto(eachClone, conformedResult, unitOfWork);
        }
        int size = fromDatabase.size();
        for (int index = 0; index < size; index++) {
            Object eachClone = fromDatabase.get(index);
            cp.addInto(eachClone, conformedResult, unitOfWork);
        }

        if (cursor != null) {
            cursor.setObjectCollection((List)conformedResult);

            // For nested UOW must copy all in object collection to
            // initiallyConformingIndex, as some of these could have been from
            // the parent UnitOfWork.
            if (unitOfWork.isNestedUnitOfWork()) {
                for (Object clone : cursor.getObjectCollection()) {
                    indexedInterimResult.put(clone, clone);
                }
            }
            return cursor;
        } else {
            return conformedResult;
        }
    }

    /**
     * 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
     */
    @Override
    public Object execute(AbstractSession session, AbstractRecord row) throws DatabaseException {
        if (shouldCacheQueryResults()) {
            if (getContainerPolicy().overridesRead()) {
                throw QueryException.cannotCacheCursorResultsOnQuery(this);
            }
            if (shouldConformResultsInUnitOfWork()) {
                throw QueryException.cannotConformAndCacheQueryResults(this);
            }
            if (isPrepared()) {// only prepared queries can have cached results.
                Object queryResults = getQueryResults(session, row, true);
                if (queryResults != null) {
                    if (QueryMonitor.shouldMonitor()) {
                        QueryMonitor.incrementReadAllHits(this);
                    }
                    session.incrementProfile(SessionProfiler.CacheHits, this);
                    // bug6138532 - check for "cached no results" (InvalidObject singleton) in query
                    // results, and return an empty container instance as configured
                    if (queryResults == InvalidObject.instance) {
                        return getContainerPolicy().containerInstance(0);
                    }
                    Collection results = (Collection)queryResults;
                    if (session.isUnitOfWork()) {
                        ContainerPolicy policy = getContainerPolicy();
                        Object resultCollection = policy.containerInstance(results.size());
                        Object iterator = policy.iteratorFor(results);
                        while (policy.hasNext(iterator)) {
                            Object result = ((UnitOfWorkImpl)session).registerExistingObject(policy.next(iterator, session), this.descriptor, null, true);
                            policy.addInto(result, resultCollection, session);
                        }
                        return resultCollection;
                    }
                    return results;
                }
            }
            session.incrementProfile(SessionProfiler.CacheMisses, this);
        }
        if (QueryMonitor.shouldMonitor()) {
            QueryMonitor.incrementReadAllMisses(this);
        }
        return super.execute(session, row);
    }

    /**
     * INTERNAL:
     * Execute the query.
     * Get the rows and build the object from the rows.
     * @exception  DatabaseException - an error has occurred on the database
     * @return java.lang.Object collection of objects resulting from execution of query.
     */
    @Override
    protected Object executeObjectLevelReadQuery() throws DatabaseException {
        Object result = null;

        if (this.containerPolicy.overridesRead()) {
            this.executionTime = System.currentTimeMillis();
            return this.containerPolicy.execute();
        }

        if (this.descriptor.isDescriptorForInterface()) {
            Object returnValue = this.descriptor.getInterfacePolicy().selectAllObjectsUsingMultipleTableSubclassRead(this);
            this.executionTime = System.currentTimeMillis();
            return returnValue;
        }

        if (this.descriptor.hasTablePerClassPolicy() && this.descriptor.isAbstract()) {
            result = this.containerPolicy.containerInstance();

            if (this.shouldIncludeData) {
                ComplexQueryResult complexResult = new ComplexQueryResult();
                complexResult.setResult(result);
                complexResult.setData(new ArrayList());
                result = complexResult;
            }
        } else {
            Object sopObject = getTranslationRow().getSopObject();
            boolean useOptimization = false;
            if (sopObject == null) {
                useOptimization = usesResultSetAccessOptimization();
            }

            if (useOptimization) {
                DatabaseCall call = ((DatasourceCallQueryMechanism)this.queryMechanism).selectResultSet();
                this.executionTime = System.currentTimeMillis();
                Statement statement = call.getStatement();
                ResultSet resultSet = call.getResult();
                DatabaseAccessor dbAccessor = (DatabaseAccessor)getAccessor();
                boolean exceptionOccured = false;
                try {
                    if (this.session.isUnitOfWork()) {
                        result = registerResultSetInUnitOfWork(resultSet, call.getFields(), call.getFieldsArray(), (UnitOfWorkImpl)this.session, this.translationRow);
                    } else {
                        result = this.containerPolicy.containerInstance();
                        this.descriptor.getObjectBuilder().buildObjectsFromResultSetInto(this, resultSet, call.getFields(), call.getFieldsArray(), result);
                    }
                } catch (SQLException exception) {
                    exceptionOccured = true;
                    DatabaseException commException = dbAccessor.processExceptionForCommError(this.session, exception, call);
                    if (commException != null) {
                        throw commException;
                    }
                    throw DatabaseException.sqlException(exception, call, dbAccessor, this.session, false);
                } finally {
                    try {
                        if (resultSet != null) {
                            resultSet.close();
                        }
                        if (dbAccessor != null) {
                            if (statement != null) {
                                dbAccessor.releaseStatement(statement, call.getSQLString(), call, this.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, this.session, false);
                        }
                    }
                }
            } else {
                List<AbstractRecord> rows;
                if (sopObject != null) {
                    Object valuesIterator = this.containerPolicy.iteratorFor(getTranslationRow().getSopObject());
                    int size = this.containerPolicy.sizeFor(sopObject);
                    rows =  new ArrayList<>(size);
                    while (this.containerPolicy.hasNext(valuesIterator)) {
                        Object memberSopObject = this.containerPolicy.next(valuesIterator, this.session);
                        DatabaseRecord memberRow = new DatabaseRecord(0);
                        memberRow.setSopObject(memberSopObject);
                        rows.add(memberRow);
                    }
                    this.executionTime = System.currentTimeMillis();
                } else {
                    rows = getQueryMechanism().selectAllRows();
                    this.executionTime = System.currentTimeMillis();

                    // If using 1-m joins, must set all rows.
                    if (hasJoining() && this.joinedAttributeManager.isToManyJoin()) {
                        this.joinedAttributeManager.setDataResults(rows, this.session);
                    }
                    // Batch fetching in IN requires access to the rows to build the id array.
                    if ((this.batchFetchPolicy != null) && this.batchFetchPolicy.isIN()) {
                        this.batchFetchPolicy.setDataResults(rows);
                    }
                }

                if (this.session.isUnitOfWork()) {
                    result = registerResultInUnitOfWork(rows, (UnitOfWorkImpl)this.session, this.translationRow, true);//
                } else {
                    if (rows instanceof ThreadCursoredList) {
                        result = this.containerPolicy.containerInstance();
                    } else {
                        result = this.containerPolicy.containerInstance(rows.size());
                    }
                    this.descriptor.getObjectBuilder().buildObjectsInto(this, rows, result);
                }

                if (sopObject != null) {
                    if (!this.descriptor.getObjectBuilder().isSimple()) {
                        // remove sopObject so it's not stuck in any value holder.
                        for (AbstractRecord row : rows) {
                            row.setSopObject(null);
                        }
                    }
                } else {
                    if (this.shouldIncludeData) {
                        ComplexQueryResult complexResult = new ComplexQueryResult();
                        complexResult.setResult(result);
                        complexResult.setData(rows);
                        result = complexResult;
                    }
                }
            }
        }

        // Add the other (already registered) results and return them.
        if (this.descriptor.hasTablePerClassPolicy()) {
            result = this.containerPolicy.concatenateContainers(
                    result, this.descriptor.getTablePerClassPolicy().selectAllObjectsUsingMultipleTableSubclassRead(this), this.session);
        }

        // If the results were empty, then ensure they get cached still.
        if (shouldCacheQueryResults() && this.containerPolicy.isEmpty(result)) {
            this.temporaryCachedQueryResults = InvalidObject.instance();
        }

        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 an ArrayList of the resulting objects.
     */
    @Override
    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)getAccessor();
        boolean exceptionOccured = false;
        try {
            ResultSetMetaData metaData = resultSet.getMetaData();
            List results = new ArrayList();
            ObjectBuilder builder = this.descriptor.getObjectBuilder();
            while (resultSet.next()) {
                results.add(builder.buildObjectFromResultSet(this, this.joinedAttributeManager, resultSet, session, accessor, metaData, platform, call.getFields(), call.getFieldsArray()));
            }
            return results;
        } 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.
     */
    @Override
    public Object extractRemoteResult(Transporter transporter) {
        return ((DistributedSession)getSession()).getObjectsCorrespondingToAll(transporter.getObject(), transporter.getObjectDescriptors(), new IdentityHashMap(), this, getContainerPolicy());
    }

    /**
     * INTERNAL:
     * Return the query's container policy.
     */
    public ContainerPolicy getContainerPolicy() {
        return containerPolicy;
    }

    /**
     * INTERNAL:
     * Returns the specific default redirector for this query type.  There are numerous default query redirectors.
     * See ClassDescriptor for their types.
     */
    @Override
    protected QueryRedirector getDefaultRedirector() {
        return descriptor.getDefaultReadAllQueryRedirector();
    }

    /**
     * PUBLIC:
     * @return Expression - the start with expression used to generated the hierarchical query clause in
     * Oracle
     */
    public Expression getStartWithExpression() {
        return startWithExpression;
    }

    /**
     * PUBLIC:
     * @return Expression - the connect by expression used to generate the hierarchical query caluse in Oracle
     */
    public Expression getConnectByExpression() {
        return connectByExpression;
    }

    /**
     * PUBLIC:
     * @return {@literal List<Expression>} - the ordering expressions used to generate the hierarchical query clause in Oracle
     */
    public List<Expression> getOrderSiblingsByExpressions() {
        return orderSiblingsByExpressions;
    }

    /**
     * PUBLIC:
     * @return Direction - the direction in which the hierarchy is traversed
     */
    public Direction getDirection() {
        return direction;
    }

    /**
     * INTERNAL:
     * Verify that we have hierarchical query expressions
     */
    public boolean hasHierarchicalExpressions() {
        return ((this.startWithExpression != null) || (this.connectByExpression != null) || (this.orderSiblingsByExpressions != null));
    }

    /**
     * INTERNAL:
     * Return true if the query uses default properties.
     * This is used to determine if this query is cacheable.
     * i.e. does not use any properties that may conflict with another query
     * with the same JPQL or selection criteria.
     */
    @Override
    public boolean isDefaultPropertiesQuery() {
        return super.isDefaultPropertiesQuery()
            && (!hasBatchReadAttributes())
            && (!hasHierarchicalExpressions())
            && (!this.containerPolicy.isCursorPolicy());
    }

    /**
     * INTERNAL:
     * Return if the query is equal to the other.
     * This is used to allow dynamic expression query SQL to be cached.
     */
    @Override
    public boolean equals(Object object) {
        if (this == object) {
            return true;
        }
        if (!super.equals(object)) {
            return false;
        }
        ReadAllQuery query = (ReadAllQuery) object;
        if (!this.containerPolicy.equals(query.containerPolicy)) {
            return false;
        }
        return true;
    }

    /**
     * PUBLIC:
     * Return if this is a read all query.
     */
    @Override
    public boolean isReadAllQuery() {
        return true;
    }

    /**
     * INTERNAL:
     * Prepare the receiver for execution in a session.
     */
    @Override
    protected void prepare() throws QueryException {
        if ((!isReportQuery()) && prepareFromCachedQuery()) {
            return;
        }
        super.prepare();

        this.containerPolicy.prepare(this, getSession());

        if (hasJoining() && isExpressionQuery()) {
            // 1-m join fetching with pagination requires an order by.
            if (this.joinedAttributeManager.isToManyJoin()
                    && ((this.maxRows > 0) || (this.firstResult > 0) || this.containerPolicy.isCursorPolicy())) {
                if (!hasOrderByExpressions()) {
                    for (DatabaseField primaryKey : this.descriptor.getPrimaryKeyFields()) {
                        addOrdering(getExpressionBuilder().getField(primaryKey));
                    }
                }
            }
        }

        if (this.containerPolicy.overridesRead()) {
            return;
        }

        if (this.descriptor.isDescriptorForInterface()) {
            return;
        }

        prepareSelectAllRows();

        if (!isReportQuery()) {
            // should be called after prepareSelectRow so that the call knows whether it returns ResultSet
            prepareResultSetAccessOptimization();
        }
    }

    /**
     * INTERNAL:
     * Prepare the query from the prepared query.
     * This allows a dynamic query to prepare itself directly from a prepared query instance.
     * This is used in the JPQL parse cache to allow preparsed queries to be used to prepare
     * dynamic queries.
     * This only copies over properties that are configured through JPQL.
     */
    @Override
    public void prepareFromQuery(DatabaseQuery query) {
        super.prepareFromQuery(query);
        if (query.isReadAllQuery()) {
            ReadAllQuery readQuery = (ReadAllQuery)query;
            this.containerPolicy = readQuery.containerPolicy;
            if (readQuery.hasHierarchicalExpressions()) {
                this.orderSiblingsByExpressions = readQuery.orderSiblingsByExpressions;
                this.connectByExpression = readQuery.connectByExpression;
                this.startWithExpression = readQuery.startWithExpression;
            }
        }
    }

    /**
     * INTERNAL:
     * Set the properties needed to be cascaded into the custom query.
     */
    @Override
    protected void prepareCustomQuery(DatabaseQuery customQuery) {
        super.prepareCustomQuery(customQuery);
        ReadAllQuery customReadQuery = (ReadAllQuery)customQuery;
        customReadQuery.containerPolicy = this.containerPolicy;
        customReadQuery.cascadePolicy = this.cascadePolicy;
        customReadQuery.shouldRefreshIdentityMapResult = this.shouldRefreshIdentityMapResult;
        customReadQuery.shouldMaintainCache = this.shouldMaintainCache;
        customReadQuery.shouldUseWrapperPolicy = this.shouldUseWrapperPolicy;
    }

    /**
     * INTERNAL:
     * Prepare the receiver for execution in a session.
     */
    @Override
    public void prepareForExecution() throws QueryException {
        super.prepareForExecution();

        this.containerPolicy.prepareForExecution();

        // Modifying the translation row here will modify it on the original
        // query which is not good. So we have to clone the translation row if
        // we are going to append tenant discriminator fields to it.
        if (descriptor.hasMultitenantPolicy()) {
            translationRow = translationRow.clone();
            descriptor.getMultitenantPolicy().addFieldsToRow(translationRow, getSession());
        }
    }

    /**
     * INTERNAL:
     * Prepare the mechanism.
     */
    protected void prepareSelectAllRows() {
        getQueryMechanism().prepareSelectAllRows();
    }

    /**
     * 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
     */
    @Override
    public Object registerResultInUnitOfWork(Object result, UnitOfWorkImpl unitOfWork, AbstractRecord arguments, boolean buildDirectlyFromRows) {
        // For bug 2612366: Conforming results in UOW extremely slow.
        // Replacing results with registered versions in the UOW is a part of
        // conforming and is now done while conforming to maximize performance.
        if (unitOfWork.hasCloneMapping() // PERF: Avoid conforming empty uow.
                    && (shouldConformResultsInUnitOfWork() || this.descriptor.shouldAlwaysConformResultsInUnitOfWork())) {
            return conformResult(result, unitOfWork, arguments, buildDirectlyFromRows);
        }

        // When building directly from rows, one of the performance benefits
        // is that we no longer have to wrap and then unwrap the originals.
        // result is just a vector, not a collection of wrapped originals.
        // Also for cursors the initial connection is automatically registered.
        if (buildDirectlyFromRows) {
            List<AbstractRecord> rows = (List<AbstractRecord>)result;
            ContainerPolicy cp = this.containerPolicy;
            int size = rows.size();
            Object clones = cp.containerInstance(size);
            if(cp.shouldAddAll()) {
                List clonesIn = new ArrayList(size);
                List<AbstractRecord> rowsIn = new ArrayList(size);
                for (int index = 0; index < size; index++) {
                    AbstractRecord row = rows.get(index);

                    // null is placed in the row collection for 1-m joining to filter duplicate rows.
                    if (row != null) {
                        Object clone = buildObject(row);
                        clonesIn.add(clone);
                        rowsIn.add(row);
                    }
                }
                cp.addAll(clonesIn, clones, unitOfWork, rowsIn, this, null, true);
            } else {
                boolean quickAdd = (clones instanceof Collection) && !this.descriptor.getObjectBuilder().hasWrapperPolicy();
                if (this.descriptor.getCachePolicy().shouldPrefetchCacheKeys()
                        && shouldMaintainCache()
                        && ! shouldRetrieveBypassCache()
                        && ((!(unitOfWork.hasCommitManager() && unitOfWork.getCommitManager().isActive())
                                && ! unitOfWork.wasTransactionBegunPrematurely()
                                && !this.descriptor.getCachePolicy().shouldIsolateObjectsInUnitOfWork()
                                && ! this.descriptor.getCachePolicy().shouldIsolateProtectedObjectsInUnitOfWork())
                                || (unitOfWork.isClassReadOnly(this.getReferenceClass(), this.getDescriptor())))){
                    Object[] pkList = new Object[size];
                    for (int i = 0; i< size; ++i){
                        pkList[i] = getDescriptor().getObjectBuilder().extractPrimaryKeyFromRow(rows.get(i), session);
                    }
                    setPrefetchedCacheKeys(unitOfWork.getParentIdentityMapSession(this).getIdentityMapAccessorInstance().getAllCacheKeysFromIdentityMapWithEntityPK(pkList, descriptor));
                }
                for (int index = 0; index < size; index++) {
                    AbstractRecord row = rows.get(index);

                    // null is placed in the row collection for 1-m joining to filter duplicate rows.
                    if (row != null) {
                        Object clone = buildObject(row);
                        if (quickAdd) {
                            ((Collection)clones).add(clone);
                        } else {
                            cp.addInto(clone, clones, unitOfWork, row, this, null, true);
                        }
                    }
                }
            }
            return clones;
        }

        ContainerPolicy cp;
        Cursor cursor = null;

        // If the query is redirected then the collection returned might no longer
        // correspond to the original container policy.  CR#2342-S.M.
        if (getRedirector() != null) {
            cp = ContainerPolicy.buildPolicyFor(result.getClass());
        } else {
            cp = this.containerPolicy;
        }

        // In the case of cursors just register the initially read collection.
        if (cp.isCursorPolicy()) {
            cursor = (Cursor)result;
            // In nested UnitOfWork session might have been session of the parent.
            cursor.setSession(unitOfWork);
            cp = ContainerPolicy.buildPolicyFor(ClassConstants.Vector_class);
            result = cursor.getObjectCollection();
        }

        Object clones = cp.containerInstance(cp.sizeFor(result));
        AbstractSession sessionToUse = unitOfWork.getParent();
        for (Object iter = cp.iteratorFor(result); cp.hasNext(iter);) {
            Object object = cp.next(iter, sessionToUse);
            Object clone = registerIndividualResult(object, null, unitOfWork, this.joinedAttributeManager, null);
            cp.addInto(clone, clones, unitOfWork);
        }
        if (cursor != null) {
            cursor.setObjectCollection((Vector)clones);
            return cursor;
        } else {
            return clones;
        }
    }

    /**
     * INTERNAL:
     * Version of the previous method for ResultSet optimization.
     *
     * @return the final (conformed, refreshed, wrapped) UnitOfWork query result
     */
    public Object registerResultSetInUnitOfWork(ResultSet resultSet, Vector fields, DatabaseField[] fieldsArray, UnitOfWorkImpl unitOfWork, AbstractRecord arguments) throws SQLException {
        // TODO: add support for Conforming results in UOW - currently conforming in uow is not compatible with ResultSet optimization.

        ContainerPolicy cp = this.containerPolicy;
        Object clones = cp.containerInstance();
        ResultSetMetaData metaData = resultSet.getMetaData();
        boolean hasNext = resultSet.next();
        if (hasNext) {
            // TODO: possibly add support for SortedListContainerPolicy (cp.shouldAddAll() == true) - this policy currently is not compatible with ResultSet optimization
            boolean quickAdd = (clones instanceof Collection) && !this.descriptor.getObjectBuilder().hasWrapperPolicy();
            DatabaseAccessor dbAccessor = (DatabaseAccessor)getAccessor();
            boolean useSimple = this.descriptor.getObjectBuilder().isSimple();
            AbstractSession executionSession = getExecutionSession();
            DatabasePlatform platform = dbAccessor.getPlatform();
            boolean optimizeData = platform.shouldOptimizeDataConversion();
            if (useSimple) {
                // None of the fields are relational - the row could be reused, just clear all the values.
                SimpleResultSetRecord row = new SimpleResultSetRecord(fields, fieldsArray, resultSet, metaData, dbAccessor, executionSession, 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.
                    row.setShouldKeepValues(true);
                }
                while (hasNext) {
                    Object clone = buildObject(row);
                    if (quickAdd) {
                        ((Collection)clones).add(clone);
                    } else {
                        // TODO: investigate is it possible to support MappedKeyMapPolicy - this policy currently is not compatible with ResultSet optimization
                        cp.addInto(clone, clones, unitOfWork);
                    }
                    row.reset();
                    hasNext = resultSet.next();
                }
            } else {
                boolean shouldKeepRow = this.descriptor.getObjectBuilder().shouldKeepRow();
                while (hasNext) {
                    ResultSetRecord row = new ResultSetRecord(fields, fieldsArray, resultSet, metaData, dbAccessor, executionSession, platform, optimizeData);
                    Object clone = buildObject(row);
                    if (quickAdd) {
                        ((Collection)clones).add(clone);
                    } else {
                        // TODO: investigate is it possible to support MappedKeyMapPolicy - this policy currently is not compatible with ResultSet optimization
                        cp.addInto(clone, clones, unitOfWork);
                    }

                    if (shouldKeepRow) {
                        if (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.
                            row.removeResultSet();
                        } else {
                            row.removeNonIndirectionValues();
                        }
                    }
                    hasNext = resultSet.next();
                }
            }
        }
        return clones;
    }

    /**
     * INTERNAL:
     * Execute the query through remote session.
     */
    @Override
    public Object remoteExecute() {
        if (this.containerPolicy.overridesRead()) {
            return this.containerPolicy.remoteExecute();
        }

        Object cacheHit = checkEarlyReturn(this.session, this.translationRow);
        if (cacheHit != null) {
            return cacheHit;
        }

        return super.remoteExecute();
    }

    /**
     * INTERNAL:
     * replace the value holders in the specified result object(s)
     */
    @Override
    public Map replaceValueHoldersIn(Object object, RemoteSessionController controller) {
        return controller.replaceValueHoldersInAll(object, getContainerPolicy());
    }

    /**
     * PUBLIC:
     * Set the container policy. Used to support different containers
     * (e.g. Collections, Maps).
     */
    public void setContainerPolicy(ContainerPolicy containerPolicy) {
        // CR#... a container policy is always required, default is vector,
        // required for deployment XML.
        if (containerPolicy == null) {
            return;
        }
        this.containerPolicy = containerPolicy;
        setIsPrepared(false);
    }

    /**
     * PUBLIC:
     * Set the Hierarchical Query Clause for the query
     * <p>Example:
     * <p>Expression startWith = builder.get("id").equal(Integer.valueOf(100)); //can be any expression which identifies a set of employees
     * <p>Expression connectBy = builder.get("managedEmployees"); //indicated the relationship that the hierarchy is based on, must be self-referential
     * <p>Vector orderBy = new Vector();
     * <p>orderBy.addElement(builder.get("startDate"));
     * <p>readAllQuery.setHierarchicalQueryClause(startWith, connectBy, orderBy);
     *
     * <p>This query would generate SQL like this:
     * <p>SELECT * FROM EMPLOYEE START WITH ID=100 CONNECT BY PRIOR ID = MANAGER_ID ORDER SIBLINGS BY START_DATE
     *
     * @param startWith Describes the START WITH clause of the query - null if not needed
     * @param connectBy This should be a query key expression which indicates an attribute who's mapping describes the hierarchy
     * @param orderSiblingsExpressions Contains expressions which indicate fields to be included in the ORDER SIBLINGS BY clause - null if not required
     */
    public void setHierarchicalQueryClause(Expression startWith, Expression connectBy, List<Expression> orderSiblingsExpressions) {
        setHierarchicalQueryClause(startWith, connectBy, orderSiblingsExpressions, null);
    }

    /**
     * PUBLIC: Set the Hierarchical Query Clause for the query, specifying the
     * hierarchy traversal direction
     * <p>
     * Example:
     * <p>
     * Expression startWith = builder.get("id").equal(Integer.valueOf(100)); //can
     * be any expression which identifies a set of employees <br>
     * Expression connectBy = builder.get("managedEmployees"); //indicated the
     * relationship that the hierarchy is based on, must be self-referential <br>
     * Vector orderBy = new Vector(); <br>
     * orderBy.addElement(builder.get("startDate")); <br>
     * readAllQuery.setHierarchicalQueryClause(startWith, connectBy, orderBy,
     * Direction.CHILD_TO_PARENT);
     *
     * <p>
     * This query would generate SQL like this:
     * <p>
     * SELECT * FROM EMPLOYEE START WITH ID=100 CONNECT BY ID = PRIOR MANAGER_ID
     * ORDER SIBLINGS BY START_DATE
     *
     * @param startWith
     *            Describes the START WITH clause of the query - null if not
     *            needed
     * @param connectBy
     *            This should be a query key expression which indicates an
     *            attribute who's mapping describes the hierarchy
     * @param orderSiblingsExpressions
     *            Contains expressions which indicate fields to be included in
     *            the ORDER SIBLINGS BY clause - null if not required
     * @param direction
     *            The direction in which the hierarchy is traversed; if not
     *            specified, CHILD_TO_PARENT is used for OneToOne relationships
     *            and PARENT_TO_CHILD is used for collections
     */
    public void setHierarchicalQueryClause(Expression startWith, Expression connectBy, List<Expression> orderSiblingsExpressions, Direction direction) {
        this.startWithExpression = startWith;
        this.connectByExpression = connectBy;
        this.orderSiblingsByExpressions = orderSiblingsExpressions;
        this.direction = direction;
        setIsPrepared(false);
    }

    /**
     * PUBLIC:
     * Configure the mapping to use an instance of the specified container class
     * to hold the target objects.
     * <p>jdk1.2.x: The container class must implement (directly or indirectly) the Collection interface.
     * <p>jdk1.1.x: The container class must be a subclass of Vector.
     */
    public void useCollectionClass(Class concreteClass) {
        // Set container policy.
        setContainerPolicy(ContainerPolicy.buildPolicyFor(concreteClass));

    }

    /**
     * PUBLIC:
     * Use a CursoredStream as the result collection.
     * The initial read size is 10 and page size is 5.
     */
    public void useCursoredStream() {
        useCursoredStream(10, 5);
    }

    /**
     * PUBLIC:
     * Use a CursoredStream as the result collection.
     * @param initialReadSize the initial number of objects to read
     * @param pageSize the number of objects to read when more objects
     * are needed from the database
     */
    public void useCursoredStream(int initialReadSize, int pageSize) {
        setContainerPolicy(new CursoredStreamPolicy(this, initialReadSize, pageSize));
    }

    /**
     * PUBLIC:
     * Use a CursoredStream as the result collection.
     * @param initialReadSize the initial number of objects to read
     * @param pageSize the number of objects to read when more objects
     * are needed from the database
     * @param sizeQuery a query that will return the size of the result set;
     * this must be set if an expression is not used (i.e. custom SQL)
     */
    public void useCursoredStream(int initialReadSize, int pageSize, ValueReadQuery sizeQuery) {
        setContainerPolicy(new CursoredStreamPolicy(this, initialReadSize, pageSize, sizeQuery));
    }

    /**
     * PUBLIC:
     * Configure the query to use an instance of the specified container class
     * to hold the result objects. The key used to index the value in the Map
     * is the value returned by a call to the specified zero-argument method.
     * The method must be implemented by the class (or a superclass) of the
     * value to be inserted into the Map.
     * <p>jdk1.2.x: The container class must implement (directly or indirectly) the Map interface.
     * <p>jdk1.1.x: The container class must be a subclass of Hashtable.
     * <p>The referenceClass must set before calling this method.
     */
    public void useMapClass(Class concreteClass, String methodName) {
        // the reference class has to be specified before coming here
        if (getReferenceClass() == null) {
            throw QueryException.referenceClassMissing(this);
        }
        ContainerPolicy policy = ContainerPolicy.buildPolicyFor(concreteClass);
        policy.setKeyName(methodName, getReferenceClass().getName());
        setContainerPolicy(policy);
    }

    /**
     * PUBLIC:
     * Use a ScrollableCursor as the result collection.
     */
    public void useScrollableCursor() {
        useScrollableCursor(10);
    }

    /**
     * PUBLIC:
     * Use a ScrollableCursor as the result collection.
     * @param pageSize the number of elements to be read into a the cursor
     * when more elements are needed from the database.
     */
    public void useScrollableCursor(int pageSize) {
        setContainerPolicy(new ScrollableCursorPolicy(this, pageSize));
    }

    /**
     * PUBLIC:
     * Use a ScrollableCursor as the result collection.
     * @param policy the scrollable cursor policy allows for additional result set options.
     * Example:<p>
     * ScrollableCursorPolicy policy = new ScrollableCursorPolicy()<p>
     * policy.setResultSetType(ScrollableCursorPolicy.TYPE_SCROLL_INSENSITIVE);<p>
     * query.useScrollableCursor(policy);
     */
    public void useScrollableCursor(ScrollableCursorPolicy policy) {
        policy.setQuery(this);
        setContainerPolicy(policy);
    }

    /**
     * INTERNAL:
     * Indicates whether the query can use ResultSet optimization.
     * The method is called when the query is prepared,
     * so it should refer only to the attributes that cannot be altered without re-preparing the query.
     * If the query is a clone and the original has been already prepared
     * this method will be called to set a (transient and therefore set to null) usesResultSetOptimization attribute.
     */
    @Override
    public boolean supportsResultSetAccessOptimizationOnPrepare() {
        if (!super.supportsResultSetAccessOptimizationOnPrepare()) {
            return false;
        }
        return !this.containerPolicy.isMappedKeyMapPolicy() && !this.containerPolicy.shouldAddAll() &&  // MappedKeyMapPolicy requires the whole row, OrderListContainerPolicy requires all rows.
                !this.descriptor.shouldAlwaysConformResultsInUnitOfWork();  // will be supported when conformResult method is adapted to use ResultSet;
    }

    /**
     * INTERNAL:
     * Indicates whether the query can use ResultSet optimization.
     * Note that the session must be already set.
     * The method is called when the query is executed,
     * so it should refer only to the attributes that can be altered without re-preparing the query.
     */
    @Override
    public boolean supportsResultSetAccessOptimizationOnExecute() {
        if (!super.supportsResultSetAccessOptimizationOnExecute()) {
            return false;
        }
        return !shouldConformResultsInUnitOfWork(); // could be supported if conformResult method is adapted to use ResultSetAccessOptimization
    }
}
