/*
 * 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 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
    }
}
