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

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
//     07/13/2009-2.0 Guy Pelletier
//       - 277039: JPA 2.0 Cache Usage Settings
//     corteggiano, Frank Schwarz, Tom Ware - Fix for bug Bug 320254 - EL 2.1.0 JPA: Query with hint eclipselink.batch
//              and org.eclipse.persistence.exceptions.QueryException.queryHintNavigatedNonExistantRelationship
//     10/29/2010-2.2 Michael O'Brien
//       - 325167: Make reserved # bind parameter char generic to enable native SQL pass through
//     06/30/2011-2.3.1 Guy Pelletier
//       - 341940: Add disable/enable allowing native queries
//     06/30/2015-2.6.0 Will Dazey
//       - 471487: Fixed eclipselink.jdbc.timeout hint not applying correctly to SQLCall
//     09/03/2015 - Will Dazey
//       - 456067 : Added support for defining query timeout units
//     09/04/2018-3.0 Ravi Babu Tummuru
//       - 538183: SETTING QUERYHINTS.CURSOR ON A NAMEDQUERY THROWS QUERYEXCEPTION
//     09/02/2019-3.0 Alexandre Jacob
//        - 527415: Fix code when locale is tr, az or lt
package org.eclipse.persistence.internal.jpa;

import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.sql.Time;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.concurrent.TimeUnit;

import jakarta.persistence.CacheRetrieveMode;
import jakarta.persistence.CacheStoreMode;

import org.eclipse.persistence.exceptions.ConversionException;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.exceptions.QueryException;


import org.eclipse.persistence.queries.DatabaseQuery;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.queries.ReadAllQuery;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.annotations.BatchFetchType;
import org.eclipse.persistence.annotations.CacheType;
import org.eclipse.persistence.config.*;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.invalidation.DailyCacheInvalidationPolicy;
import org.eclipse.persistence.descriptors.invalidation.TimeToLiveCacheInvalidationPolicy;
import org.eclipse.persistence.descriptors.partitioning.PartitioningPolicy;
import org.eclipse.persistence.history.AsOfClause;
import org.eclipse.persistence.history.AsOfSCNClause;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.localization.ExceptionLocalization;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
import org.eclipse.persistence.internal.security.PrivilegedNewInstanceFromClass;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.mappings.ForeignReferenceMapping;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.queries.AttributeGroup;
import org.eclipse.persistence.queries.CursorPolicy;
import org.eclipse.persistence.queries.CursoredStreamPolicy;
import org.eclipse.persistence.queries.DataModifyQuery;
import org.eclipse.persistence.queries.DataReadQuery;
import org.eclipse.persistence.queries.DeleteAllQuery;
import org.eclipse.persistence.queries.DirectReadQuery;
import org.eclipse.persistence.queries.FetchGroup;
import org.eclipse.persistence.queries.InMemoryQueryIndirectionPolicy;
import org.eclipse.persistence.queries.LoadGroup;
import org.eclipse.persistence.queries.ModifyAllQuery;
import org.eclipse.persistence.queries.ModifyQuery;
import org.eclipse.persistence.queries.ObjectBuildingQuery;
import org.eclipse.persistence.queries.QueryRedirector;
import org.eclipse.persistence.queries.ReadObjectQuery;
import org.eclipse.persistence.queries.ReadQuery;
import org.eclipse.persistence.queries.ReportQuery;
import org.eclipse.persistence.queries.ResultSetMappingQuery;
import org.eclipse.persistence.queries.ScrollableCursorPolicy;
import org.eclipse.persistence.queries.UpdateAllQuery;
import org.eclipse.persistence.queries.ValueReadQuery;

/**
 * The class processes query hints.
 *
 * EclipseLink query hints and their values defined in org.eclipse.persistence.config package.
 *
 * To add a new query hint:
 *   Define a new hint in QueryHints;
 *   Add a class containing hint's values if required to config package (like CacheUsage);
 *      Alternatively values defined in HintValues may be used - Refresh and BindParameters hints do that.
 *   Add an inner class to this class extending Hint corresponding to the new hint (like CacheUsageHint);
 *      The first constructor parameter is hint name; the second is default value;
 *      In constructor
 *          provide 2-dimensional value array in case the values should be translated (currently all Hint classes do that);
 *              in case translation is not required provide a single-dimension array (no such examples yet).
 *   In inner class Hint static initializer addHint an instance of the new hint class (like addHint(new CacheUsageHint())).
 *
 * @see QueryHints
 * @see HintValues
 * @see CacheUsage
 * @see PessimisticLock
 */
public class QueryHintsHandler {

    public static final String QUERY_HINT_PROPERTY = "eclipselink.query.hints";

    private QueryHintsHandler() {
    }

    /**
     * Verifies the hints.
     *
     * If session != null then logs a FINEST message for each hint.
     * queryName parameter used only for identifying the query in messages,
     * if it's null then "null" will be used.
     * Throws IllegalArgumentException in case the hint value is illegal.
     */
    public static void verify(Map hints, String queryName, AbstractSession session) {
        if(hints == null) {
            return;
        }
        Iterator it = hints.entrySet().iterator();
        while(it.hasNext()) {
            Map.Entry entry = (Map.Entry)it.next();
            String hintName = (String)entry.getKey();
            verify(hintName, entry.getValue(), queryName, session);
        }
    }

    /**
     * Verifies the hint.
     *
     * If session != null then logs a FINEST message.
     * queryName parameter used only for identifying the query in messages,
     * if it's null then "null" will be used.
     * Throws IllegalArgumentException in case the hint value is illegal.
     */
    public static void verify(String hintName, Object hintValue, String queryName, AbstractSession session) {
        Hint.verify(hintName, shouldUseDefault(hintValue), hintValue, queryName, session);
    }

    /**
     * Applies the hints to the query.
     * Throws IllegalArgumentException in case the hint value is illegal.
     */
    public static DatabaseQuery apply(Map<String, Object> hints, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
        if (hints == null) {
            return query;
        }
        DatabaseQuery hintQuery = query;
        for (Map.Entry<String, Object> entry : hints.entrySet()) {
            String hintName = entry.getKey();
            if (entry.getValue() instanceof Object[]) {
                Object[] values = (Object[])entry.getValue();
                for (int index = 0; index < values.length; index++) {
                    hintQuery = apply(hintName, values[index], hintQuery, loader, activeSession);
                }
            } else {
                hintQuery = apply(hintName, entry.getValue(), hintQuery, loader, activeSession);
            }
        }
        return hintQuery;
    }

    /**
     * Applies the hint to the query.
     * Throws IllegalArgumentException in case the hint value is illegal.
     */
    public static DatabaseQuery apply(String hintName, Object hintValue, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
        return Hint.apply(hintName, shouldUseDefault(hintValue), hintValue, query, loader, activeSession);
    }

    /**
     * Common hint value processing into an boolean value. If the hint is
     * null, false is returned. Those methods that need to handle a null hint
     * to be something other than false should not call this method.
     */
    public static boolean parseBooleanHint(Object hint) {
        if (hint == null) {
            return false;
        } else {
            return Boolean.parseBoolean(hint.toString());
        }
    }

    /**
     * Common hint value processing into an integer value. If the hint is
     * null, -1 is returned.
     */
    public static int parseIntegerHint(Object hint, String hintName) {
        if (hint == null) {
            return -1;
        } else {
            try {
                return Integer.parseInt(hint.toString());
            } catch (NumberFormatException e) {
                throw QueryException.queryHintContainedInvalidIntegerValue(hintName, hint, e);
            }
        }
    }

    /**
     * Empty String hintValue indicates that the default hint value
     * should be used.
     */
    protected static boolean shouldUseDefault(Object hintValue) {
        return (hintValue != null) &&  (hintValue instanceof String) && (((String)hintValue).length() == 0);
    }

    public static Set<String> getSupportedHints(){
        return Hint.getSupportedHints();
    }

    /**
     * Define a generic Hint.
     * Hints should subclass this and override the applyToDatabaseQuery
     * and set the valueArray if the set of valid values is finite.
     */
    protected static abstract class Hint {
        static HashMap<String, Hint> mainMap = new HashMap<>();
        Object[] valueArray;
        HashMap<String, Object> valueMap;
        String name;
        String defaultValue;
        Object defaultValueToApply;
        boolean valueToApplyMayBeNull;

        static {
            addHint(new BindParametersHint());
            addHint(new CacheUsageHint());
            addHint(new CacheRetrieveModeHint());
            addHint(new CacheRetrieveModeLegacyHint());
            addHint(new CacheStoreModeHint());
            addHint(new CacheStoreModeLegacyHint());
            addHint(new QueryTypeHint());
            addHint(new PessimisticLockHint());
            addHint(new PessimisticLockScope());
            addHint(new PessimisticLockTimeoutHint());
            addHint(new PessimisticLockTimeoutUnitHint());
            addHint(new RefreshHint());
            addHint(new CascadePolicyHint());
            addHint(new BatchHint());
            addHint(new BatchTypeHint());
            addHint(new BatchSizeHint());
            addHint(new FetchHint());
            addHint(new LeftFetchHint());
            addHint(new ReadOnlyHint());
            addHint(new JDBCTimeoutHint());
            //Enhancement
            addHint(new QueryTimeoutUnitHint());
            //Enhancement
            addHint(new QueryTimeoutHint());
            addHint(new JDBCFetchSizeHint());
            addHint(new JDBCMaxRowsHint());
            addHint(new JDBCFirstResultHint());
            addHint(new ResultCollectionTypeHint());
            addHint(new RedirectorHint());
            addHint(new PartitioningHint());
            addHint(new QueryCacheHint());
            addHint(new QueryCacheSizeHint());
            addHint(new QueryCacheExpiryHint());
            addHint(new QueryCacheExpiryTimeOfDayHint());
            addHint(new MaintainCacheHint());
            addHint(new PrepareHint());
            addHint(new CacheStatementHint());
            addHint(new FlushHint());
            addHint(new HintHint());
            addHint(new NativeConnectionHint());
            addHint(new CursorHint());
            addHint(new CursorInitialSizeHint());
            addHint(new CursorPageSizeHint());
            addHint(new ScrollableCursorHint());
            addHint(new CursorSizeHint());
            addHint(new FetchGroupHint());
            addHint(new FetchGraphHint());
            addHint(new FetchGroupNameHint());
            addHint(new FetchGroupDefaultHint());
            addHint(new FetchGroupAttributeHint());
            addHint(new FetchGroupLoadHint());
            addHint(new LoadGroupHint());
            addHint(new LoadGroupAttributeHint());
            addHint(new LoadGraphHint());
            addHint(new ExclusiveHint());
            addHint(new InheritanceJoinHint());
            addHint(new AsOfHint());
            addHint(new AsOfSCNHint());
            addHint(new ResultTypeHint());
            addHint(new ResultSetTypeHint());
            addHint(new ResultSetConcurrencyHint());
            addHint(new IndirectionPolicyHint());
            addHint(new QueryCacheTypeHint());
            addHint(new QueryCacheIgnoreNullHint());
            addHint(new QueryCacheInvalidateOnChangeHint());
            addHint(new QueryCacheRandomizedExpiryHint());
            // 325167: Make reserved # bind parameter char generic to enable native SQL pass through
            addHint(new ParameterDelimiterHint());
            addHint(new CompositeMemberHint());
            addHint(new AllowNativeSQLQueryHint());
            addHint(new BatchWriteHint());
            addHint(new ResultSetAccess());
            addHint(new SerializedObject());
            addHint(new ReturnNameValuePairsHint());
        }

        Hint(String name, String defaultValue) {
            this.name = name;
            this.defaultValue = defaultValue;
        }

        abstract DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession);

        static void verify(String hintName, boolean shouldUseDefault, Object hintValue, String queryName, AbstractSession session) {
            Hint hint = mainMap.get(hintName);
            if(hint == null) {
                if(session != null) {
                    session.log(SessionLog.FINEST, SessionLog.QUERY, "unknown_query_hint", new Object[]{getPrintValue(queryName), hintName});
                }
                return;
            }

            hint.verify(hintValue, shouldUseDefault, queryName, session);
        }

        void verify(Object hintValue, boolean shouldUseDefault, String queryName, AbstractSession session) {
            if(shouldUseDefault) {
                hintValue = defaultValue;
            }
            if(session != null) {
                session.log(SessionLog.FINEST, SessionLog.QUERY, "query_hint", new Object[]{getPrintValue(queryName), name, getPrintValue(hintValue)});
            }
            if(!shouldUseDefault && valueMap != null && !valueMap.containsKey(getUpperCaseString(hintValue))) {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-query-hint-value",new Object[]{getPrintValue(queryName), name, getPrintValue(hintValue)}));
            }
        }

        static DatabaseQuery apply(String hintName, boolean shouldUseDefault, Object hintValue, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            Hint hint = mainMap.get(hintName);
            if (hint == null) {
                // unknown hint name - silently ignored.
                return query;
            }

            Map<String, Object> existingHints = (Map<String, Object>)query.getProperty(QUERY_HINT_PROPERTY);
            if (existingHints == null){
                existingHints = new HashMap<String, Object>();
                query.setProperty(QUERY_HINT_PROPERTY, existingHints);
            }
            existingHints.put(hintName, hintValue);

            return hint.apply(hintValue, shouldUseDefault, query, loader, activeSession);
        }

        DatabaseQuery apply(Object hintValue, boolean shouldUseDefault, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            Object valueToApply = hintValue;
            if (shouldUseDefault) {
                valueToApply = defaultValueToApply;
            } else {
                if( valueMap != null) {
                    String key = getUpperCaseString(hintValue);
                    valueToApply = valueMap.get(key);
                    if (valueToApply == null) {
                        boolean wrongKey = true;
                        if (valueToApplyMayBeNull) {
                            wrongKey = !valueMap.containsKey(key);
                        }
                        if (wrongKey) {
                            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-query-hint-value",new Object[]{getQueryId(query), name, getPrintValue(hintValue)}));
                        }
                    }
                }
            }
            return applyToDatabaseQuery(valueToApply, query, loader, activeSession);
        }

        static String getQueryId(DatabaseQuery query) {
            String queryId = query.getName();
            if(queryId == null) {
                queryId = query.getEJBQLString();
            }
            return getPrintValue(queryId);
        }

        static String getPrintValue(Object hintValue) {
            return hintValue != null ? hintValue.toString() : "null";
        }

        static String getUpperCaseString(Object hintValue) {
            return hintValue != null ? hintValue.toString().toUpperCase(Locale.ROOT) : null;
        }

        static Class<?> loadClass(String className, DatabaseQuery query, ClassLoader loader) throws QueryException {
            try {
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                    try {
                        return AccessController.doPrivileged(new PrivilegedClassForName<>(className, true, loader));
                    } catch (PrivilegedActionException exception) {
                        throw QueryException.classNotFoundWhileUsingQueryHint(query, className, exception.getException());
                    }
                } else {
                    return PrivilegedAccessHelper.getClassForName(className, true, loader);
                }
            } catch (ClassNotFoundException exception){
                throw QueryException.classNotFoundWhileUsingQueryHint(query, className, exception);
            }
        }

        static <T> T newInstance(Class<T> theClass, DatabaseQuery query, String hint) {
            try {
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    return AccessController.doPrivileged(new PrivilegedNewInstanceFromClass<T>(theClass));
                } else {
                    return PrivilegedAccessHelper.newInstanceFromClass(theClass);
                }
            } catch (Exception exception) {
                throw QueryException.errorInstantiatedClassForQueryHint(exception, query, theClass, hint);
            }
        }

        void initialize() {
            if(valueArray != null) {
                valueMap = new HashMap<>(valueArray.length);
                if(valueArray instanceof Object[][]) {
                    Object[][] valueArray2 = (Object[][])valueArray;
                    for(int i=0; i<valueArray2.length; i++) {
                        valueMap.put(getUpperCaseString(valueArray2[i][0]), valueArray2[i][1]);
                        if(valueArray2[i][1] == null) {
                            valueToApplyMayBeNull = true;
                        }
                    }
                } else {
                    for(int i=0; i<valueArray.length; i++) {
                        valueMap.put(getUpperCaseString(valueArray[i]), valueArray[i]);
                        if(valueArray[i] == null) {
                            valueToApplyMayBeNull = true;
                        }
                    }
                }
                defaultValueToApply = valueMap.get(defaultValue.toUpperCase(Locale.ROOT));
            }
        }

        static void addHint(Hint hint) {
            hint.initialize();
            mainMap.put(hint.name, hint);
        }

        static Set<String> getSupportedHints(){
            return mainMap.keySet();
        }
    }

    /**
     * This hint can be used to indicate whether or not a ResultSetMapping query should
     * return populated DatabaseRecords vs. raw data.  This hint is particularly useful
     * when the structure of the returned data is not known.
     */
    protected static class ReturnNameValuePairsHint extends Hint {
        ReturnNameValuePairsHint() {
            super(QueryHints.RETURN_NAME_VALUE_PAIRS, HintValues.FALSE);
            valueArray = new Object[][] {
                {HintValues.TRUE, Boolean.TRUE},
                {HintValues.FALSE, Boolean.FALSE}
            };
        }

        /**
         * Applies the given hint value to the query if it is non-null.  The given query
         * is expected to be a ResultSetMappingQuery instance.
         * @throws IllegalArgumentException if 'query' is not a ResultSetMappingQuery instance
         */
        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isResultSetMappingQuery()) {
                if (valueToApply != null) {
                    ((ResultSetMappingQuery) query).setShouldReturnNameValuePairs(((Boolean) valueToApply));
                }
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class BindParametersHint extends Hint {
        BindParametersHint() {
            super(QueryHints.BIND_PARAMETERS, HintValues.PERSISTENCE_UNIT_DEFAULT);
            valueArray = new Object[][] {
                {HintValues.PERSISTENCE_UNIT_DEFAULT, null},
                {HintValues.TRUE, Boolean.TRUE},
                {HintValues.FALSE, Boolean.FALSE}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (valueToApply == null) {
                query.ignoreBindAllParameters();
            } else {
                query.setShouldBindAllParameters(((Boolean)valueToApply).booleanValue());
            }
            return query;
        }
    }

    protected static class AllowNativeSQLQueryHint extends Hint {
        AllowNativeSQLQueryHint() {
            super(QueryHints.ALLOW_NATIVE_SQL_QUERY, HintValues.PERSISTENCE_UNIT_DEFAULT);
            valueArray = new Object[][] {
                {HintValues.FALSE, Boolean.FALSE},
                {HintValues.TRUE, Boolean.TRUE}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            query.setAllowNativeSQLQuery((Boolean) valueToApply);
            return query;
        }
    }

    /**
     * INTERNAL:
     * 325167: Make reserved # bind parameter char generic to enable native SQL pass through
     */
    protected static class ParameterDelimiterHint extends Hint {
        ParameterDelimiterHint() {
            super(QueryHints.PARAMETER_DELIMITER, ParameterDelimiterType.DEFAULT);
            // No valueArray modification is required for unrestricted values
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            // Only change the default set by the DatabaseQuery constructor - if an override is requested via the Hint
            if (valueToApply != null) {
                query.setParameterDelimiter(((String)valueToApply));
            }
            return query;
        }
    }

    protected static class CacheRetrieveModeHint extends Hint {
        CacheRetrieveModeHint() {
            this(QueryHints.CACHE_RETRIEVE_MODE, CacheRetrieveMode.USE.name());
        }

        CacheRetrieveModeHint(String name, String defaultValue) {
            super(name, defaultValue);
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectLevelReadQuery()) {
                if (valueToApply.equals(CacheRetrieveMode.BYPASS) || valueToApply.equals(CacheRetrieveMode.BYPASS.name())) {
                    query.retrieveBypassCache();
                }

                // CacheRetrieveMode.USE will use the EclipseLink default of
                // shouldCheckDescriptorForCacheUsage which in most cases is CheckCacheByPrimaryKey.
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }

            return query;
        }
    }

    protected static class CacheRetrieveModeLegacyHint extends CacheRetrieveModeHint {
        CacheRetrieveModeLegacyHint() {
            super("jakarta.persistence.cacheRetrieveMode", CacheRetrieveMode.USE.name());
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (activeSession != null) {
                String[] properties = new String[] { QueryHints.CACHE_RETRIEVE_MODE, "jakarta.persistence.cacheRetrieveMode" };
                activeSession.log(SessionLog.INFO, SessionLog.TRANSACTION, "deprecated_property", properties);
            }
            return super.applyToDatabaseQuery(valueToApply, query, loader, activeSession);
        }
    }

    protected static class CacheStoreModeHint extends Hint {
        CacheStoreModeHint() {
            this(QueryHints.CACHE_STORE_MODE, CacheStoreMode.USE.name());
        }

        CacheStoreModeHint(String name, String defaultValue) {
            super(name, defaultValue);
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (valueToApply.equals(CacheStoreMode.BYPASS) || valueToApply.equals(CacheStoreMode.BYPASS.name())) {
                query.storeBypassCache();
            } else if (valueToApply.equals(CacheStoreMode.REFRESH) || valueToApply.equals(CacheStoreMode.REFRESH.name())) {
                if (query.isObjectLevelReadQuery()) {
                    ((ObjectLevelReadQuery) query).refreshIdentityMapResult();
                } else {
                    throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
                }
            }

            // CacheStoreMode.USE will use the EclipseLink default maintainCache.

            return query;
        }
    }

    protected static class CacheStoreModeLegacyHint extends CacheStoreModeHint {
        CacheStoreModeLegacyHint() {
            super("jakarta.persistence.cacheStoreMode", CacheStoreMode.USE.name());
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (activeSession != null) {
                String[] properties = new String[] { QueryHints.CACHE_STORE_MODE, "jakarta.persistence.cacheStoreMode" };
                activeSession.log(SessionLog.INFO, SessionLog.TRANSACTION, "deprecated_property", properties);
            }
            return super.applyToDatabaseQuery(valueToApply, query, loader, activeSession);
        }
    }

    /**
     * Configure the cache usage of the query.
     * As many of the usages require a ReadObjectQuery, the hint may also require to change the query type.
     */
    protected static class CacheUsageHint extends Hint {
        CacheUsageHint() {
            super(QueryHints.CACHE_USAGE, CacheUsage.DEFAULT);
            valueArray = new Object[][] {
                {CacheUsage.UseEntityDefault, ObjectLevelReadQuery.UseDescriptorSetting},
                {CacheUsage.DoNotCheckCache, ObjectLevelReadQuery.DoNotCheckCache},
                {CacheUsage.CheckCacheByExactPrimaryKey, ObjectLevelReadQuery.CheckCacheByExactPrimaryKey},
                {CacheUsage.CheckCacheByPrimaryKey, ObjectLevelReadQuery.CheckCacheByPrimaryKey},
                {CacheUsage.CheckCacheThenDatabase, ObjectLevelReadQuery.CheckCacheThenDatabase},
                {CacheUsage.CheckCacheOnly, ObjectLevelReadQuery.CheckCacheOnly},
                {CacheUsage.ConformResultsInUnitOfWork, ObjectLevelReadQuery.ConformResultsInUnitOfWork},
                {CacheUsage.NoCache, ModifyAllQuery.NO_CACHE},
                {CacheUsage.Invalidate, ModifyAllQuery.INVALIDATE_CACHE}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectLevelReadQuery()) {
                int cacheUsage = (Integer) valueToApply;
                ((ObjectLevelReadQuery)query).setCacheUsage(cacheUsage);
                if (cacheUsage == ObjectLevelReadQuery.CheckCacheByExactPrimaryKey
                        || cacheUsage == ObjectLevelReadQuery.CheckCacheByPrimaryKey
                        || cacheUsage == ObjectLevelReadQuery.CheckCacheThenDatabase) {
                    ReadObjectQuery newQuery = new ReadObjectQuery();
                    newQuery.copyFromQuery(query);
                    return newQuery;
                }
            } else if (query.isModifyAllQuery()) {
                int cacheUsage = (Integer) valueToApply;
                ((ModifyAllQuery)query).setCacheUsage(cacheUsage);
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    /**
     * Configure the cache usage of the query.
     * As many of the usages require a ReadObjectQuery, the hint may also require to change the query type.
     */
    protected static class BatchWriteHint extends Hint {
        BatchWriteHint() {
            super(QueryHints.BATCH_WRITING, HintValues.FALSE);
            valueArray = new Object[][] {
                    {HintValues.FALSE, Boolean.FALSE},
                    {HintValues.TRUE, Boolean.TRUE}
                };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isDataReadQuery()) {
                DataModifyQuery newQuery = new DataModifyQuery();
                newQuery.copyFromQuery(query);
                newQuery.setIsBatchExecutionSupported((Boolean) valueToApply);
                return newQuery;
            } else if (query.isModifyQuery()) {
                ((ModifyQuery)query).setIsBatchExecutionSupported((Boolean) valueToApply);
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class CascadePolicyHint extends Hint {
        CascadePolicyHint() {
            super(QueryHints.REFRESH_CASCADE, CascadePolicy.DEFAULT);
            valueArray = new Object[][] {
                {CascadePolicy.NoCascading, DatabaseQuery.NoCascading},
                {CascadePolicy.CascadePrivateParts, DatabaseQuery.CascadePrivateParts},
                {CascadePolicy.CascadeAllParts, DatabaseQuery.CascadeAllParts},
                {CascadePolicy.CascadeByMapping, DatabaseQuery.CascadeByMapping}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            query.setCascadePolicy((Integer)valueToApply);
            return query;
        }
    }

    /**
     * Configure the type of the query.
     */
    protected static class QueryTypeHint extends Hint {
        QueryTypeHint() {
            super(QueryHints.QUERY_TYPE, QueryType.DEFAULT);
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (valueToApply.equals(QueryType.DEFAULT)) {
                return query;
            }
            // Allows an query type, or a custom query class.
            DatabaseQuery newQuery = query;
            if (valueToApply.equals(QueryType.ReadAll)) {
                newQuery = new ReadAllQuery();
            } else if (valueToApply.equals(QueryType.ReadObject)) {
                newQuery = new ReadObjectQuery();
            } else if (valueToApply.equals(QueryType.Report)) {
                newQuery = new ReportQuery();
                if (query.isObjectLevelReadQuery()) {
                    ((ReportQuery)newQuery).addAttribute("root", ((ReportQuery)newQuery).getExpressionBuilder());
                }
            } else if (valueToApply.equals(QueryType.ResultSetMapping)) {
                newQuery = new ResultSetMappingQuery();
            } else if (valueToApply.equals(QueryType.UpdateAll)) {
                newQuery = new UpdateAllQuery();
            } else if (valueToApply.equals(QueryType.DeleteAll)) {
                newQuery = new DeleteAllQuery();
            } else if (valueToApply.equals(QueryType.DataModify)) {
                newQuery = new DataModifyQuery();
            } else if (valueToApply.equals(QueryType.DataRead)) {
                newQuery = new DataReadQuery();
            } else if (valueToApply.equals(QueryType.DirectRead)) {
                newQuery = new DirectReadQuery();
            } else if (valueToApply.equals(QueryType.ValueRead)) {
                newQuery = new ValueReadQuery();
            } else {
                Class<?> queryClass = loadClass((String)valueToApply, query, loader);
                newQuery = (DatabaseQuery)newInstance(queryClass, query, QueryHints.QUERY_TYPE);
            }
            newQuery.copyFromQuery(query);
            return newQuery;
        }
    }

    protected static class PessimisticLockHint extends Hint {
        PessimisticLockHint() {
            super(QueryHints.PESSIMISTIC_LOCK, PessimisticLock.DEFAULT);
            valueArray = new Object[][] {
                {PessimisticLock.NoLock, ObjectLevelReadQuery.NO_LOCK},
                {PessimisticLock.Lock, ObjectLevelReadQuery.LOCK},
                {PessimisticLock.LockNoWait, ObjectLevelReadQuery.LOCK_NOWAIT}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectBuildingQuery()) {
                ((ObjectBuildingQuery)query).setLockMode((Short) valueToApply);
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class PessimisticLockScope extends Hint {
        PessimisticLockScope() {
            super(QueryHints.PESSIMISTIC_LOCK_SCOPE, jakarta.persistence.PessimisticLockScope.NORMAL.name());
            valueArray = new Object[] {
                jakarta.persistence.PessimisticLockScope.NORMAL.name(),
                jakarta.persistence.PessimisticLockScope.EXTENDED.name()
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectLevelReadQuery()) {
                boolean shouldExtend = valueToApply.equals(jakarta.persistence.PessimisticLockScope.EXTENDED.name());
                ObjectLevelReadQuery olrQuery = (ObjectLevelReadQuery)query;
                olrQuery.setShouldExtendPessimisticLockScope(shouldExtend);
                if(shouldExtend) {
                    olrQuery.extendPessimisticLockScope();
                }
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class PessimisticLockTimeoutHint extends Hint {
        PessimisticLockTimeoutHint() {
            super(QueryHints.PESSIMISTIC_LOCK_TIMEOUT, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectLevelReadQuery()) {
                ((ObjectLevelReadQuery) query).setWaitTimeout(QueryHintsHandler.parseIntegerHint(valueToApply, QueryHints.PESSIMISTIC_LOCK_TIMEOUT));
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }

            return query;
        }
    }

    protected static class PessimisticLockTimeoutUnitHint extends Hint {
        PessimisticLockTimeoutUnitHint() {
            super(QueryHints.PESSIMISTIC_LOCK_TIMEOUT_UNIT, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectLevelReadQuery()) {
                TimeUnit unit = TimeUnit.valueOf((String)valueToApply);
                ((ObjectLevelReadQuery) query).setWaitTimeoutUnit(unit);
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }

            return query;
        }
    }
    
    protected static class RefreshHint extends Hint {
        RefreshHint() {
            super(QueryHints.REFRESH, HintValues.FALSE);
            valueArray = new Object[][] {
                {HintValues.FALSE, Boolean.FALSE},
                {HintValues.TRUE, Boolean.TRUE}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectBuildingQuery()) {
                ((ObjectBuildingQuery)query).setShouldRefreshIdentityMapResult((Boolean) valueToApply);
                // Set default cascade to be by mapping.
                if (!query.shouldCascadeParts()) {
                    query.cascadeByMapping();
                }
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class ResultTypeHint extends Hint {
        ResultTypeHint() {
            super(QueryHints.RESULT_TYPE, ResultType.DEFAULT);
            valueArray = new Object[][] {
                {ResultType.Map, ResultType.Map},
                {ResultType.Array, ResultType.Array},
                {ResultType.Value, ResultType.Value},
                {ResultType.Attribute, ResultType.Attribute}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isDataReadQuery()) {
                if (valueToApply == ResultType.Map) {
                    ((DataReadQuery)query).setResultType(DataReadQuery.MAP);
                } else if (valueToApply == ResultType.Array) {
                    ((DataReadQuery)query).setResultType(DataReadQuery.ARRAY);
                } else if (valueToApply == ResultType.Attribute) {
                    ((DataReadQuery)query).setResultType(DataReadQuery.ATTRIBUTE);
                } else if (valueToApply == ResultType.Value) {
                    ((DataReadQuery)query).setResultType(DataReadQuery.VALUE);
                }
            } else if (query.isReportQuery()) {
                if (valueToApply == ResultType.Map) {
                    ((ReportQuery)query).setReturnType(ReportQuery.ShouldReturnReportResult);
                } else if (valueToApply == ResultType.Array) {
                    ((ReportQuery)query).setReturnType(ReportQuery.ShouldReturnArray);
                } else if (valueToApply == ResultType.Attribute) {
                    ((ReportQuery)query).setReturnType(ReportQuery.ShouldReturnSingleAttribute);
                } else if (valueToApply == ResultType.Value) {
                    ((ReportQuery)query).setReturnType(ReportQuery.ShouldReturnSingleValue);
                }
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class IndirectionPolicyHint extends Hint {
        IndirectionPolicyHint() {
            super(QueryHints.INDIRECTION_POLICY, CacheUsageIndirectionPolicy.DEFAULT);
            valueArray = new Object[][] {
                {CacheUsageIndirectionPolicy.Conform, InMemoryQueryIndirectionPolicy.SHOULD_IGNORE_EXCEPTION_RETURN_CONFORMED},
                {CacheUsageIndirectionPolicy.NotConform, InMemoryQueryIndirectionPolicy.SHOULD_IGNORE_EXCEPTION_RETURN_CONFORMED},
                {CacheUsageIndirectionPolicy.Trigger, InMemoryQueryIndirectionPolicy.SHOULD_TRIGGER_INDIRECTION},
                {CacheUsageIndirectionPolicy.Exception, InMemoryQueryIndirectionPolicy.SHOULD_THROW_INDIRECTION_EXCEPTION}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectLevelReadQuery()) {
                ((ObjectLevelReadQuery) query).setInMemoryQueryIndirectionPolicyState((Integer)valueToApply);
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class ResultSetTypeHint extends Hint {
        ResultSetTypeHint() {
            super(QueryHints.RESULT_SET_TYPE, ResultSetType.DEFAULT);
            valueArray = new Object[][] {
                {ResultSetType.Forward, ScrollableCursorPolicy.FETCH_FORWARD},
                {ResultSetType.ForwardOnly, ScrollableCursorPolicy.TYPE_FORWARD_ONLY},
                {ResultSetType.Reverse, ScrollableCursorPolicy.FETCH_REVERSE},
                {ResultSetType.ScrollInsensitive, ScrollableCursorPolicy.TYPE_SCROLL_INSENSITIVE},
                {ResultSetType.ScrollSensitive, ScrollableCursorPolicy.TYPE_SCROLL_SENSITIVE},
                {ResultSetType.Unknown, ScrollableCursorPolicy.FETCH_UNKNOWN}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            int value = (Integer)valueToApply;
            if (query.isReadAllQuery()) {
                if (!((ReadAllQuery) query).getContainerPolicy().isScrollableCursorPolicy()) {
                    ((ReadAllQuery) query).useScrollableCursor();
                }
                ((ScrollableCursorPolicy)((ReadAllQuery) query).getContainerPolicy()).setResultSetType(value);
            } else if (query.isDataReadQuery()) {
                if (!((DataReadQuery) query).getContainerPolicy().isScrollableCursorPolicy()) {
                    ((DataReadQuery) query).useScrollableCursor();
                }
                ((ScrollableCursorPolicy)((DataReadQuery) query).getContainerPolicy()).setResultSetType(value);
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class ResultSetConcurrencyHint extends Hint {
        ResultSetConcurrencyHint() {
            super(QueryHints.RESULT_SET_CONCURRENCY, ResultSetConcurrency.DEFAULT);
            valueArray = new Object[][] {
                {ResultSetConcurrency.ReadOnly, ScrollableCursorPolicy.CONCUR_READ_ONLY},
                {ResultSetConcurrency.Updatable, ScrollableCursorPolicy.CONCUR_UPDATABLE}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            int value = (Integer)valueToApply;
            if (query.isReadAllQuery()) {
                if (!((ReadAllQuery) query).getContainerPolicy().isScrollableCursorPolicy()) {
                    ((ReadAllQuery) query).useScrollableCursor();
                }
                ((ScrollableCursorPolicy)((ReadAllQuery) query).getContainerPolicy()).setResultSetConcurrency(value);
            } else if (query.isDataReadQuery()) {
                if (!((DataReadQuery) query).getContainerPolicy().isScrollableCursorPolicy()) {
                    ((DataReadQuery) query).useScrollableCursor();
                }
                ((ScrollableCursorPolicy)((DataReadQuery) query).getContainerPolicy()).setResultSetConcurrency(value);
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class ExclusiveHint extends Hint {
        ExclusiveHint() {
            super(QueryHints.EXCLUSIVE_CONNECTION, HintValues.FALSE);
            valueArray = new Object[][] {
                {HintValues.FALSE, Boolean.FALSE},
                {HintValues.TRUE, Boolean.TRUE}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectBuildingQuery()) {
                ((ObjectBuildingQuery)query).setShouldUseExclusiveConnection((Boolean) valueToApply);
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class InheritanceJoinHint extends Hint {
        InheritanceJoinHint() {
            super(QueryHints.INHERITANCE_OUTER_JOIN, HintValues.FALSE);
            valueArray = new Object[][] {
                {HintValues.FALSE, Boolean.FALSE},
                {HintValues.TRUE, Boolean.TRUE}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectLevelReadQuery()) {
                ((ObjectLevelReadQuery)query).setShouldOuterJoinSubclasses((Boolean) valueToApply);
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class FetchGroupDefaultHint extends Hint {
        FetchGroupDefaultHint() {
            super(QueryHints.FETCH_GROUP_DEFAULT, HintValues.TRUE);
            valueArray = new Object[][] {
                {HintValues.FALSE, Boolean.FALSE},
                {HintValues.TRUE, Boolean.TRUE}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectLevelReadQuery()) {
                ((ObjectLevelReadQuery)query).setShouldUseDefaultFetchGroup((Boolean) valueToApply);
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class FetchGroupNameHint extends Hint {
        FetchGroupNameHint() {
            super(QueryHints.FETCH_GROUP_NAME, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectLevelReadQuery()) {
                ((ObjectLevelReadQuery)query).setFetchGroupName((String)valueToApply);
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class FetchGroupHint extends Hint {
        FetchGroupHint() {
            super(QueryHints.FETCH_GROUP, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectLevelReadQuery()) {
                if(valueToApply != null) {
                    ((ObjectLevelReadQuery)query).setFetchGroup(((AttributeGroup)valueToApply).toFetchGroup());
                } else {
                    ((ObjectLevelReadQuery)query).setFetchGroup(null);
                }
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class FetchGraphHint extends Hint {
        FetchGraphHint() {
            super(QueryHints.JPA_FETCH_GRAPH, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectLevelReadQuery()) {
                if(valueToApply != null) {
                    if (valueToApply instanceof String){
                        AttributeGroup eg = activeSession.getAttributeGroups().get(valueToApply);
                        if (eg != null){
                            FetchGroup fg = eg.toFetchGroup();
                            fg.setShouldLoadAll(true);
                            ((ObjectLevelReadQuery)query).setFetchGroup(fg);
                        }else{
                            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("no_entity_graph_of_name", new Object[]{valueToApply}));
                        }
                    }else if (valueToApply instanceof EntityGraphImpl){
                        FetchGroup fg = ((EntityGraphImpl)valueToApply).getAttributeGroup().toFetchGroup();
                        fg.setShouldLoadAll(true);
                        ((ObjectLevelReadQuery)query).setFetchGroup(fg);
                    }else{
                        throw new IllegalArgumentException(ExceptionLocalization.buildMessage("not_usable_passed_to_entitygraph_hint", new Object[]{QueryHints.JPA_FETCH_GRAPH, valueToApply}));
                    }
                } else {
                    ((ObjectLevelReadQuery)query).setFetchGroup(null);
                }
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class FetchGroupAttributeHint extends Hint {
        FetchGroupAttributeHint() {
            super(QueryHints.FETCH_GROUP_ATTRIBUTE, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectLevelReadQuery()) {
                FetchGroup fetchGroup = ((ObjectLevelReadQuery)query).getFetchGroup();
                if (fetchGroup == null) {
                    fetchGroup = new FetchGroup();
                    ((ObjectLevelReadQuery)query).setFetchGroup(fetchGroup);
                }
                fetchGroup.addAttribute((String)valueToApply);
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class FetchGroupLoadHint extends Hint {
        FetchGroupLoadHint() {
            super(QueryHints.FETCH_GROUP_LOAD, HintValues.TRUE);
            valueArray = new Object[][] {
                    {HintValues.FALSE, Boolean.FALSE},
                    {HintValues.TRUE, Boolean.TRUE}
                };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectLevelReadQuery()) {
                FetchGroup fetchGroup = ((ObjectLevelReadQuery)query).getFetchGroup();
                if (fetchGroup == null) {
                    fetchGroup = new FetchGroup();
                    ((ObjectLevelReadQuery)query).setFetchGroup(fetchGroup);
                }
                fetchGroup.setShouldLoadAll((Boolean)valueToApply);
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class LoadGroupHint extends Hint {
        LoadGroupHint() {
            super(QueryHints.LOAD_GROUP, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectLevelReadQuery()) {
                if(valueToApply != null) {
                    ((ObjectLevelReadQuery)query).setLoadGroup(((AttributeGroup)valueToApply).toLoadGroup());
                } else {
                    ((ObjectLevelReadQuery)query).setLoadGroup(null);
                }
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class LoadGraphHint extends Hint {
        LoadGraphHint() {
            super(QueryHints.JPA_LOAD_GRAPH, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectLevelReadQuery()) {
                if(valueToApply != null) {
                    if (valueToApply instanceof String){
                        AttributeGroup eg = activeSession.getAttributeGroups().get(valueToApply);
                        if (eg != null){
                            ((ObjectLevelReadQuery)query).setLoadGroup(eg.toLoadGroup());
                        }else{
                            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("no_entity_graph_of_name", new Object[]{valueToApply}));
                        }
                    }else if (valueToApply instanceof EntityGraphImpl){
                        ((ObjectLevelReadQuery)query).setLoadGroup(((EntityGraphImpl)valueToApply).getAttributeGroup().toLoadGroup());
                    }else{
                        throw new IllegalArgumentException(ExceptionLocalization.buildMessage("not_usable_passed_to_entitygraph_hint", new Object[]{QueryHints.JPA_LOAD_GRAPH, valueToApply}));
                    }
                } else {
                    ((ObjectLevelReadQuery)query).setFetchGroup(null);
                }
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class LoadGroupAttributeHint extends Hint {
        LoadGroupAttributeHint() {
            super(QueryHints.LOAD_GROUP_ATTRIBUTE, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectLevelReadQuery()) {
                LoadGroup loadGroup = ((ObjectLevelReadQuery)query).getLoadGroup();
                if (loadGroup == null) {
                    loadGroup = new LoadGroup();
                    ((ObjectLevelReadQuery)query).setLoadGroup(loadGroup);
                }
                loadGroup.addAttribute((String)valueToApply);
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    /**
     * Define the query cache hint.
     * Only reset the query cache if unset (as other query cache properties may be set first).
     */
    protected static class QueryCacheHint extends Hint {
        QueryCacheHint() {
            super(QueryHints.QUERY_RESULTS_CACHE, HintValues.FALSE);
            valueArray = new Object[][] {
                {HintValues.FALSE, Boolean.FALSE},
                {HintValues.TRUE, Boolean.TRUE}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isReadQuery()) {
                if ((Boolean) valueToApply) {
                    if (((ReadQuery)query).getQueryResultsCachePolicy() == null) {
                        ((ReadQuery)query).cacheQueryResults();
                    }
                }
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    /**
     * Define the query cache ignore null hint.
     * Only reset the query cache if unset (as other query cache properties may be set first).
     */
    protected static class QueryCacheIgnoreNullHint extends Hint {
        QueryCacheIgnoreNullHint() {
            super(QueryHints.QUERY_RESULTS_CACHE_IGNORE_NULL, HintValues.FALSE);
            valueArray = new Object[][] {
                {HintValues.FALSE, Boolean.FALSE},
                {HintValues.TRUE, Boolean.TRUE}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isReadQuery()) {
                if (((ReadQuery)query).getQueryResultsCachePolicy() == null) {
                    ((ReadQuery)query).cacheQueryResults();
                }
                ((ReadQuery)query).getQueryResultsCachePolicy().setIsNullIgnored((Boolean) valueToApply);
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    /**
     * Define the query cache ignore null hint.
     * Only reset the query cache if unset (as other query cache properties may be set first).
     */
    protected static class QueryCacheInvalidateOnChangeHint extends Hint {
        QueryCacheInvalidateOnChangeHint() {
            super(QueryHints.QUERY_RESULTS_CACHE_INVALIDATE, HintValues.TRUE);
            valueArray = new Object[][] {
                {HintValues.FALSE, Boolean.FALSE},
                {HintValues.TRUE, Boolean.TRUE}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isReadQuery()) {
                if (((ReadQuery)query).getQueryResultsCachePolicy() == null) {
                    ((ReadQuery)query).cacheQueryResults();
                }
                ((ReadQuery)query).getQueryResultsCachePolicy().setInvalidateOnChange((Boolean) valueToApply);
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    /**
     * Define the query cache randomized expiry hint.
     * Only reset the query cache if unset (as other query cache properties may be set first).
     */
    protected static class QueryCacheRandomizedExpiryHint extends Hint {
        QueryCacheRandomizedExpiryHint() {
            super(QueryHints.QUERY_RESULTS_CACHE_RANDOMIZE_EXPIRY, HintValues.FALSE);
            valueArray = new Object[][] {
                {HintValues.FALSE, Boolean.FALSE},
                {HintValues.TRUE, Boolean.TRUE}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isReadQuery()) {
                if (((ReadQuery)query).getQueryResultsCachePolicy() == null) {
                    ((ReadQuery)query).cacheQueryResults();
                }
                if (((ReadQuery)query).getQueryResultsCachePolicy().getCacheInvalidationPolicy() == null) {
                    ((ReadQuery)query).getQueryResultsCachePolicy().setCacheInvalidationPolicy(new TimeToLiveCacheInvalidationPolicy());
                }
                ((ReadQuery)query).getQueryResultsCachePolicy().getCacheInvalidationPolicy().setIsInvalidationRandomized((Boolean) valueToApply);
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    /**
     * Define the query cache size hint.
     * Only reset the query cache if unset (as other query cache properties may be set first).
     */
    protected static class QueryCacheSizeHint extends Hint {
        QueryCacheSizeHint() {
            super(QueryHints.QUERY_RESULTS_CACHE_SIZE, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isReadQuery()) {
                ReadQuery readQuery = (ReadQuery)query;
                if (readQuery.getQueryResultsCachePolicy() == null) {
                    readQuery.cacheQueryResults();
                }
                try {
                    readQuery.getQueryResultsCachePolicy().setMaximumCachedResults(Integer.parseInt((String)valueToApply));
                } catch (NumberFormatException exception) {
                    throw QueryException.queryHintContainedInvalidIntegerValue(QueryHints.QUERY_RESULTS_CACHE_SIZE, valueToApply, exception);
                }
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    /**
     * Define the query cache expiry hint.
     * Only reset the query cache if unset (as other query cache properties may be set first).
     */
    protected static class QueryCacheExpiryHint extends Hint {
        QueryCacheExpiryHint() {
            super(QueryHints.QUERY_RESULTS_CACHE_EXPIRY, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isReadQuery()) {
                ReadQuery readQuery = (ReadQuery)query;
                if (readQuery.getQueryResultsCachePolicy() == null) {
                    readQuery.cacheQueryResults();
                }
                try {
                    readQuery.getQueryResultsCachePolicy().setCacheInvalidationPolicy(
                            new TimeToLiveCacheInvalidationPolicy(Integer.parseInt((String)valueToApply)));
                } catch (NumberFormatException exception) {
                    throw QueryException.queryHintContainedInvalidIntegerValue(QueryHints.QUERY_RESULTS_CACHE_EXPIRY, valueToApply, exception);
                }
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    /**
     * Define the query cache type hint.
     * Only reset the query cache if unset (as other query cache properties may be set first).
     */
    protected static class QueryCacheTypeHint extends Hint {
        QueryCacheTypeHint() {
            super(QueryHints.QUERY_RESULTS_CACHE_TYPE, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isReadQuery()) {
                ReadQuery readQuery = (ReadQuery)query;
                if (readQuery.getQueryResultsCachePolicy() == null) {
                    readQuery.cacheQueryResults();
                }
                if (valueToApply == null) {
                    // Leave as default.
                } else if (valueToApply.equals(CacheType.SOFT_WEAK.name())) {
                    readQuery.getQueryResultsCachePolicy().setCacheType(ClassConstants.SoftCacheWeakIdentityMap_Class);
                } else if (valueToApply.equals(CacheType.FULL.name())) {
                    readQuery.getQueryResultsCachePolicy().setCacheType(ClassConstants.FullIdentityMap_Class);
                } else if (valueToApply.equals(CacheType.WEAK.name())) {
                    readQuery.getQueryResultsCachePolicy().setCacheType(ClassConstants.WeakIdentityMap_Class);
                }  else if (valueToApply.equals(CacheType.SOFT.name())) {
                    readQuery.getQueryResultsCachePolicy().setCacheType(ClassConstants.SoftIdentityMap_Class);
                } else if (valueToApply.equals(CacheType.HARD_WEAK.name())) {
                    readQuery.getQueryResultsCachePolicy().setCacheType(ClassConstants.HardCacheWeakIdentityMap_Class);
                } else if (valueToApply.equals(CacheType.CACHE.name())) {
                    readQuery.getQueryResultsCachePolicy().setCacheType(ClassConstants.CacheIdentityMap_Class);
                } else if (valueToApply.equals(CacheType.NONE.name())) {
                    readQuery.getQueryResultsCachePolicy().setCacheType(ClassConstants.NoIdentityMap_Class);
                } else {
                    throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-query-hint-value",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
                }
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    /**
     * Define the query cache expiry time of day hint.
     * Only reset the query cache if unset (as other query cache properties may be set first).
     */
    protected static class QueryCacheExpiryTimeOfDayHint extends Hint {
        QueryCacheExpiryTimeOfDayHint() {
            super(QueryHints.QUERY_RESULTS_CACHE_EXPIRY_TIME_OF_DAY, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isReadQuery()) {
                ReadQuery readQuery = (ReadQuery)query;
                if (readQuery.getQueryResultsCachePolicy() == null) {
                    readQuery.cacheQueryResults();
                }
                try {
                    Time time = Helper.timeFromString((String)valueToApply);
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(time);
                    readQuery.getQueryResultsCachePolicy().setCacheInvalidationPolicy(
                            new DailyCacheInvalidationPolicy(calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND), 0));
                } catch (ConversionException exception) {
                    throw QueryException.queryHintContainedInvalidIntegerValue(QueryHints.QUERY_RESULTS_CACHE_EXPIRY_TIME_OF_DAY, valueToApply, exception);
                }
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class BatchHint extends Hint {
        BatchHint() {
            super(QueryHints.BATCH, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectLevelReadQuery() && !query.isReportQuery()) {
                ObjectLevelReadQuery objectQuery = (ObjectLevelReadQuery)query;
                StringTokenizer tokenizer = new StringTokenizer((String)valueToApply, ".");
                if (tokenizer.countTokens() < 2){
                    throw QueryException.queryHintDidNotContainEnoughTokens(query, QueryHints.BATCH, valueToApply);
                }
                // ignore the first token since we are assuming an alias to the primary class
                // e.g. In e.phoneNumbers we will assume "e" refers to the base of the query
                String previousToken = tokenizer.nextToken();
                objectQuery.checkDescriptor(activeSession);
                ClassDescriptor descriptor = objectQuery.getDescriptor();
                Expression expression = objectQuery.getExpressionBuilder();
                while (tokenizer.hasMoreTokens()) {
                    String token = tokenizer.nextToken();
                    DatabaseMapping mapping = descriptor.getObjectBuilder().getMappingForAttributeName(token);
                    if (mapping == null) {
                        // Allow batching of subclass mappings.
                        if (!descriptor.hasInheritance()) {
                            throw QueryException.queryHintNavigatedNonExistantRelationship(query, QueryHints.BATCH, valueToApply, previousToken + "." + token);
                        }
                    } else if (!mapping.isForeignReferenceMapping() && !mapping.isAggregateObjectMapping()) {
                        throw QueryException.queryHintNavigatedIllegalRelationship(query, QueryHints.BATCH, valueToApply, previousToken + "." + token);
                    }
                    expression = expression.get(token, false);
                    previousToken = token;
                    if (mapping != null){
                        descriptor = mapping.getReferenceDescriptor();
                    }
                }
                objectQuery.addBatchReadAttribute(expression);
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class BatchTypeHint extends Hint {
        BatchTypeHint() {
            super(QueryHints.BATCH_TYPE, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectLevelReadQuery()) {
                if (valueToApply instanceof BatchFetchType) {
                    ((ObjectLevelReadQuery) query).setBatchFetchType((BatchFetchType)valueToApply);
                } else {
                    ((ObjectLevelReadQuery) query).setBatchFetchType(BatchFetchType.valueOf((String)valueToApply));
                }
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }

            return query;
        }
    }

    protected static class BatchSizeHint extends Hint {
        BatchSizeHint() {
            super(QueryHints.BATCH_SIZE, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectLevelReadQuery()) {
                ((ObjectLevelReadQuery) query).setBatchFetchSize(QueryHintsHandler.parseIntegerHint(valueToApply, QueryHints.BATCH_SIZE));
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }

            return query;
        }
    }

    protected static class FetchHint extends Hint {
        FetchHint() {
            super(QueryHints.FETCH, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectLevelReadQuery() && !query.isReportQuery()) {
                ObjectLevelReadQuery olrq = (ObjectLevelReadQuery)query;
                StringTokenizer tokenizer = new StringTokenizer((String)valueToApply, ".");
                if (tokenizer.countTokens() < 2){
                    throw QueryException.queryHintDidNotContainEnoughTokens(query, QueryHints.FETCH, valueToApply);
                }
                // ignore the first token since we are assuming read all query
                // e.g. In e.phoneNumbers we will assume "e" refers to the base of the query
                String previousToken = tokenizer.nextToken();
                olrq.checkDescriptor(activeSession);
                ClassDescriptor descriptor = olrq.getDescriptor();
                Expression expression = olrq.getExpressionBuilder();
                while (tokenizer.hasMoreTokens()){
                    String token = tokenizer.nextToken();
                    ForeignReferenceMapping frMapping = null;
                    DatabaseMapping mapping = descriptor.getObjectBuilder().getMappingForAttributeName(token);
                    if (mapping == null){
                        throw QueryException.queryHintNavigatedNonExistantRelationship(query, QueryHints.FETCH, valueToApply, previousToken + "." + token);
                    } else if (!mapping.isForeignReferenceMapping()){
                        while (mapping.isAggregateObjectMapping() && tokenizer.hasMoreTokens()){
                            expression = expression.get(token);
                            token = tokenizer.nextToken();
                            descriptor = mapping.getReferenceDescriptor();
                            mapping = descriptor.getObjectBuilder().getMappingForAttributeName(token);
                        }
                        if (!mapping.isForeignReferenceMapping()){
                            throw QueryException.queryHintNavigatedIllegalRelationship(query, QueryHints.FETCH, valueToApply, previousToken + "." + token);
                        }
                    }
                    frMapping = (ForeignReferenceMapping)mapping;
                    descriptor = frMapping.getReferenceDescriptor();
                    if (frMapping.isCollectionMapping()){
                        expression = expression.anyOf(token, false);
                    } else {
                        expression = expression.get(token);
                    }
                    previousToken = token;
                }
                olrq.addJoinedAttribute(expression);
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class LeftFetchHint extends Hint {
        LeftFetchHint() {
            super(QueryHints.LEFT_FETCH, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectLevelReadQuery() && !query.isReportQuery()) {
                ObjectLevelReadQuery olrq = (ObjectLevelReadQuery)query;
                StringTokenizer tokenizer = new StringTokenizer((String)valueToApply, ".");
                if (tokenizer.countTokens() < 2){
                    throw QueryException.queryHintDidNotContainEnoughTokens(query, QueryHints.LEFT_FETCH, valueToApply);
                }
                // ignore the first token since we are assuming read all query
                // e.g. In e.phoneNumbers we will assume "e" refers to the base of the query
                String previousToken = tokenizer.nextToken();
                olrq.checkDescriptor(activeSession);
                ClassDescriptor descriptor = olrq.getDescriptor();
                Expression expression = olrq.getExpressionBuilder();
                while (tokenizer.hasMoreTokens()){
                    String token = tokenizer.nextToken();
                    ForeignReferenceMapping frMapping = null;
                    DatabaseMapping mapping = descriptor.getObjectBuilder().getMappingForAttributeName(token);
                    if (mapping == null){
                        throw QueryException.queryHintNavigatedNonExistantRelationship(query, QueryHints.LEFT_FETCH, valueToApply, previousToken + "." + token);
                    } else if (!mapping.isForeignReferenceMapping()){
                        while (mapping.isAggregateObjectMapping() && tokenizer.hasMoreTokens()){
                            expression = expression.get(token);
                            token = tokenizer.nextToken();
                            descriptor = mapping.getReferenceDescriptor();
                            mapping = descriptor.getObjectBuilder().getMappingForAttributeName(token);
                        }
                        if (!mapping.isForeignReferenceMapping()){
                            throw QueryException.queryHintNavigatedIllegalRelationship(query, QueryHints.LEFT_FETCH, valueToApply, previousToken + "." + token);
                        }
                    }
                    frMapping = (ForeignReferenceMapping)mapping;
                    descriptor = frMapping.getReferenceDescriptor();
                    if (frMapping.isCollectionMapping()){
                        expression = expression.anyOfAllowingNone(token, false);
                    } else {
                        expression = expression.getAllowingNull(token);
                    }
                    previousToken = token;
                }
                olrq.addJoinedAttribute(expression);
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class ReadOnlyHint extends Hint {
        ReadOnlyHint() {
            super(QueryHints.READ_ONLY, HintValues.FALSE);
            valueArray = new Object[][] {
                {HintValues.FALSE, Boolean.FALSE},
                {HintValues.TRUE, Boolean.TRUE}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectLevelReadQuery()) {
                ((ObjectLevelReadQuery)query).setIsReadOnly((Boolean) valueToApply);
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class NativeConnectionHint extends Hint {
        NativeConnectionHint() {
            super(QueryHints.NATIVE_CONNECTION, HintValues.FALSE);
            valueArray = new Object[][] {
                {HintValues.FALSE, Boolean.FALSE},
                {HintValues.TRUE, Boolean.TRUE}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            query.setIsNativeConnectionRequired((Boolean) valueToApply);
            return query;
        }
    }

    protected static class CursorHint extends Hint {
        CursorHint() {
            super(QueryHints.CURSOR, HintValues.FALSE);
            valueArray = new Object[][] {
                {HintValues.FALSE, Boolean.FALSE},
                {HintValues.TRUE, Boolean.TRUE}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (!(Boolean) valueToApply) {
                if (query.isReadAllQuery()) {
                    if (((ReadAllQuery) query).getContainerPolicy().isCursoredStreamPolicy()) {
                        ((ReadAllQuery) query).setContainerPolicy(ContainerPolicy.buildDefaultPolicy());
                    }
                } else if (query.isDataReadQuery()) {
                    if (((DataReadQuery) query).getContainerPolicy().isCursoredStreamPolicy()) {
                        ((DataReadQuery) query).setContainerPolicy(ContainerPolicy.buildDefaultPolicy());
                    }
                }
            } else {
                if (query.isReadAllQuery()) {
                    if (!((ReadAllQuery) query).getContainerPolicy().isCursoredStreamPolicy()) {
                        ((ReadAllQuery) query).useCursoredStream();
                    }
                } else if (query.isDataReadQuery()) {
                    if (!((DataReadQuery) query).getContainerPolicy().isCursoredStreamPolicy()) {
                        ((DataReadQuery) query).useCursoredStream();
                    }
                } else {
                    throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
                }
            }

            query.setIsPrepared(false);

            return query;
        }
    }

    protected static class CursorInitialSizeHint extends Hint {
        CursorInitialSizeHint() {
            super(QueryHints.CURSOR_INITIAL_SIZE, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isReadAllQuery()) {
                if (!((ReadAllQuery) query).getContainerPolicy().isCursoredStreamPolicy()) {
                    ((ReadAllQuery) query).useCursoredStream();
                }
                ((CursoredStreamPolicy)((ReadAllQuery) query).getContainerPolicy()).setInitialReadSize(QueryHintsHandler.parseIntegerHint(valueToApply, QueryHints.CURSOR_INITIAL_SIZE));
            } else if (query.isDataReadQuery()) {
                if (!((DataReadQuery) query).getContainerPolicy().isCursoredStreamPolicy()) {
                    ((DataReadQuery) query).useCursoredStream();
                }
                ((CursoredStreamPolicy)((DataReadQuery) query).getContainerPolicy()).setInitialReadSize(QueryHintsHandler.parseIntegerHint(valueToApply, QueryHints.CURSOR_INITIAL_SIZE));
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }

            return query;
        }
    }

    protected static class CursorPageSizeHint extends Hint {
        CursorPageSizeHint() {
            super(QueryHints.CURSOR_PAGE_SIZE, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isReadAllQuery()) {
                if (!((ReadAllQuery) query).getContainerPolicy().isCursorPolicy()) {
                    ((ReadAllQuery) query).useCursoredStream();
                }
                ((CursorPolicy)((ReadAllQuery) query).getContainerPolicy()).setPageSize(QueryHintsHandler.parseIntegerHint(valueToApply, QueryHints.CURSOR_PAGE_SIZE));
            } else if (query.isDataReadQuery()) {
                if (!((DataReadQuery) query).getContainerPolicy().isCursorPolicy()) {
                    ((DataReadQuery) query).useCursoredStream();
                }
                ((CursorPolicy)((DataReadQuery) query).getContainerPolicy()).setPageSize(QueryHintsHandler.parseIntegerHint(valueToApply, QueryHints.CURSOR_PAGE_SIZE));
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }

            return query;
        }
    }

    protected static class CursorSizeHint extends Hint {
        CursorSizeHint() {
            super(QueryHints.CURSOR_SIZE, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isReadAllQuery()) {
                if (!((ReadAllQuery) query).getContainerPolicy().isCursoredStreamPolicy()) {
                    ((ReadAllQuery) query).useCursoredStream();
                }
                ((CursoredStreamPolicy)((ReadAllQuery) query).getContainerPolicy()).setSizeQuery(new ValueReadQuery((String)valueToApply));
            } else if (query.isDataReadQuery()) {
                if (!((DataReadQuery) query).getContainerPolicy().isCursoredStreamPolicy()) {
                    ((DataReadQuery) query).useCursoredStream();
                }
                ((CursoredStreamPolicy)((ReadAllQuery) query).getContainerPolicy()).setSizeQuery(new ValueReadQuery((String)valueToApply));
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }

            return query;
        }
    }

    protected static class ScrollableCursorHint extends Hint {
        ScrollableCursorHint() {
            super(QueryHints.SCROLLABLE_CURSOR, HintValues.FALSE);
            valueArray = new Object[][] {
                {HintValues.FALSE, Boolean.FALSE},
                {HintValues.TRUE, Boolean.TRUE}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (!(Boolean) valueToApply) {
                if (query.isReadAllQuery()) {
                    if (((ReadAllQuery) query).getContainerPolicy().isScrollableCursorPolicy()) {
                        ((ReadAllQuery) query).setContainerPolicy(ContainerPolicy.buildDefaultPolicy());
                    }
                } else if (query.isDataReadQuery()) {
                    if (((DataReadQuery) query).getContainerPolicy().isScrollableCursorPolicy()) {
                        ((DataReadQuery) query).setContainerPolicy(ContainerPolicy.buildDefaultPolicy());
                    }
                }
            } else {
                if (query.isReadAllQuery()) {
                    if (!((ReadAllQuery) query).getContainerPolicy().isScrollableCursorPolicy()) {
                        ((ReadAllQuery) query).useScrollableCursor();
                    }
                } else if (query.isDataReadQuery()) {
                    if (!((DataReadQuery) query).getContainerPolicy().isScrollableCursorPolicy()) {
                        ((DataReadQuery) query).useScrollableCursor();
                    }
                } else {
                    throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
                }
            }

            return query;
        }
    }

    protected static class MaintainCacheHint extends Hint {
        MaintainCacheHint() {
            super(QueryHints.MAINTAIN_CACHE, HintValues.FALSE);
            valueArray = new Object[][] {
                {HintValues.FALSE, Boolean.FALSE},
                {HintValues.TRUE, Boolean.TRUE}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            query.setShouldMaintainCache((Boolean) valueToApply);
            return query;
        }
    }

    protected static class PrepareHint extends Hint {
        PrepareHint() {
            super(QueryHints.PREPARE, HintValues.FALSE);
            valueArray = new Object[][] {
                {HintValues.FALSE, Boolean.FALSE},
                {HintValues.TRUE, Boolean.TRUE}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            query.setShouldPrepare((Boolean) valueToApply);
            return query;
        }
    }

    protected static class CacheStatementHint extends Hint {
        CacheStatementHint() {
            super(QueryHints.CACHE_STATMENT, HintValues.FALSE);
            valueArray = new Object[][] {
                {HintValues.FALSE, Boolean.FALSE},
                {HintValues.TRUE, Boolean.TRUE}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            query.setShouldCacheStatement((Boolean) valueToApply);
            return query;
        }
    }

    protected static class FlushHint extends Hint {
        FlushHint() {
            super(QueryHints.FLUSH, HintValues.FALSE);
            valueArray = new Object[][] {
                {HintValues.FALSE, Boolean.FALSE},
                {HintValues.TRUE, Boolean.TRUE}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            query.setFlushOnExecute((Boolean)valueToApply);
            return query;
        }
    }

    protected static class HintHint extends Hint {
        HintHint() {
            super(QueryHints.HINT, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            query.setHintString((String)valueToApply);
            return query;
        }
    }

    protected static class JDBCTimeoutHint extends Hint {
        JDBCTimeoutHint() {
            super(QueryHints.JDBC_TIMEOUT, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            query.setQueryTimeout(QueryHintsHandler.parseIntegerHint(valueToApply, QueryHints.JDBC_TIMEOUT));
            query.setIsPrepared(false);
            return query;
        }
    }

    //Bug #456067: Added support for user defining the timeout units to use
    protected static class QueryTimeoutUnitHint extends Hint {
        QueryTimeoutUnitHint() {
            super(QueryHints.QUERY_TIMEOUT_UNIT, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            try {
                TimeUnit unit = TimeUnit.valueOf((String)valueToApply);
                query.setQueryTimeoutUnit(unit);
            }
            catch(IllegalArgumentException e) {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    //Bug #456067: Added support for query hint "jakarta.persistence.query.timeout" defined in the spec
    protected static class QueryTimeoutHint extends Hint {
        QueryTimeoutHint() {
            super(QueryHints.QUERY_TIMEOUT, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            query.setQueryTimeout(QueryHintsHandler.parseIntegerHint(valueToApply, QueryHints.QUERY_TIMEOUT));
            query.setIsPrepared(false);
            return query;
        }
    }

    protected static class JDBCFetchSizeHint extends Hint {
        JDBCFetchSizeHint() {
            super(QueryHints.JDBC_FETCH_SIZE, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isReadQuery()) {
                ((ReadQuery) query).setFetchSize(QueryHintsHandler.parseIntegerHint(valueToApply, QueryHints.JDBC_FETCH_SIZE));
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }

            return query;
        }
    }

    protected static class AsOfHint extends Hint {
        AsOfHint() {
            super(QueryHints.AS_OF, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectLevelReadQuery()) {
                ((ObjectLevelReadQuery) query).setAsOfClause(new AsOfClause(Helper.timestampFromString((String)valueToApply)));
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }

            return query;
        }
    }

    protected static class AsOfSCNHint extends Hint {
        AsOfSCNHint() {
            super(QueryHints.AS_OF_SCN, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectLevelReadQuery()) {
                ((ObjectLevelReadQuery) query).setAsOfClause(new AsOfSCNClause(QueryHintsHandler.parseIntegerHint(valueToApply, QueryHints.AS_OF_SCN)));
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }

            return query;
        }
    }

    protected static class JDBCMaxRowsHint extends Hint {
        JDBCMaxRowsHint() {
            super(QueryHints.JDBC_MAX_ROWS, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isReadQuery()) {
                ((ReadQuery) query).setMaxRows(QueryHintsHandler.parseIntegerHint(valueToApply, QueryHints.JDBC_MAX_ROWS));
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class JDBCFirstResultHint extends Hint {
        JDBCFirstResultHint() {
            super(QueryHints.JDBC_FIRST_RESULT, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isReadQuery()) {
                ((ReadQuery) query).setFirstResult(QueryHintsHandler.parseIntegerHint(valueToApply, QueryHints.JDBC_FIRST_RESULT));
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class ResultCollectionTypeHint extends Hint {
        ResultCollectionTypeHint() {
            super(QueryHints.RESULT_COLLECTION_TYPE, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isReadAllQuery()) {
                Class collectionClass = null;
                if (valueToApply instanceof String) {
                    collectionClass = loadClass((String)valueToApply, query, loader);
                } else {
                    collectionClass = (Class)valueToApply;
                }
                ((ReadAllQuery)query).useCollectionClass(collectionClass);
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class RedirectorHint extends Hint {
        RedirectorHint() {
            super(QueryHints.QUERY_REDIRECTOR, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            // Can be an instance, class, or class name.
            try {
                Object redirector = valueToApply;
                if (valueToApply instanceof Class) {
                    redirector = newInstance((Class)valueToApply, query, QueryHints.QUERY_REDIRECTOR);
                } else if (valueToApply instanceof String) {
                    Class<?> redirectorClass = loadClass((String)valueToApply, query, loader);
                    redirector = newInstance(redirectorClass, query, QueryHints.QUERY_REDIRECTOR);
                }
                query.setRedirector((QueryRedirector)redirector);
            } catch (ClassCastException exception){
                throw QueryException.unableToSetRedirectorOnQueryFromHint(query,QueryHints.QUERY_REDIRECTOR, valueToApply.getClass().getName(), exception);
            }
            return query;
        }
    }

    protected static class PartitioningHint extends Hint {
        PartitioningHint() {
            super(QueryHints.PARTITIONING, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            // Can be an instance, class, or name.
            Object policy = valueToApply;
            if (valueToApply instanceof Class) {
                policy = newInstance((Class)valueToApply, query, QueryHints.PARTITIONING);
            } else if (valueToApply instanceof String) {
                policy = activeSession.getProject().getPartitioningPolicy((String)valueToApply);
                if (policy == null) {
                    throw DescriptorException.missingPartitioningPolicy((String)valueToApply, null, null);
                }
            }
            query.setPartitioningPolicy((PartitioningPolicy)policy);
            return query;
        }
    }

    protected static class CompositeMemberHint extends Hint {
        CompositeMemberHint() {
            super(QueryHints.COMPOSITE_UNIT_MEMBER, "");
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            query.setSessionName((String)valueToApply);
            return query;
        }
    }

    protected static class ResultSetAccess extends Hint {
        ResultSetAccess() {
            super(QueryHints.RESULT_SET_ACCESS, HintValues.PERSISTENCE_UNIT_DEFAULT);
            valueArray = new Object[][] {
                {HintValues.PERSISTENCE_UNIT_DEFAULT, null},
                {HintValues.TRUE, Boolean.TRUE},
                {HintValues.FALSE, Boolean.FALSE}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectLevelReadQuery()) {
                if (valueToApply != null) {
                    ((ObjectLevelReadQuery)query).setIsResultSetAccessOptimizedQuery((Boolean)valueToApply);
                } else {
                    ((ObjectLevelReadQuery)query).clearIsResultSetOptimizedQuery();
                }
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }

    protected static class SerializedObject extends Hint {
        SerializedObject() {
            super(QueryHints.SERIALIZED_OBJECT, HintValues.FALSE);
            valueArray = new Object[][] {
                {HintValues.TRUE, Boolean.TRUE},
                {HintValues.FALSE, Boolean.FALSE}
            };
        }

        @Override
        DatabaseQuery applyToDatabaseQuery(Object valueToApply, DatabaseQuery query, ClassLoader loader, AbstractSession activeSession) {
            if (query.isObjectLevelReadQuery()) {
                ((ObjectLevelReadQuery)query).setShouldUseSerializedObjectPolicy((Boolean)valueToApply);
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-type-for-query-hint",new Object[]{getQueryId(query), name, getPrintValue(valueToApply)}));
            }
            return query;
        }
    }
}
