@Override
  @SuppressWarnings({"deprecation"})
  public BaseQueryImpl setHint(String hintName, Object value) {
    checkOpen(true);
    boolean applied = false;
    try {
      if (HINT_TIMEOUT.equals(hintName)) {
        applied = applyTimeoutHint(ConfigurationHelper.getInteger(value));
      } else if (SPEC_HINT_TIMEOUT.equals(hintName)) {
        // convert milliseconds to seconds
        int timeout =
            (int) Math.round(ConfigurationHelper.getInteger(value).doubleValue() / 1000.0);
        applied = applyTimeoutHint(timeout);
      } else if (AvailableSettings.LOCK_TIMEOUT.equals(hintName)) {
        applied = applyLockTimeoutHint(ConfigurationHelper.getInteger(value));
      } else if (HINT_COMMENT.equals(hintName)) {
        applied = applyCommentHint((String) value);
      } else if (HINT_FETCH_SIZE.equals(hintName)) {
        applied = applyFetchSizeHint(ConfigurationHelper.getInteger(value));
      } else if (HINT_CACHEABLE.equals(hintName)) {
        applied = applyCacheableHint(ConfigurationHelper.getBoolean(value));
      } else if (HINT_CACHE_REGION.equals(hintName)) {
        applied = applyCacheRegionHint((String) value);
      } else if (HINT_READONLY.equals(hintName)) {
        applied = applyReadOnlyHint(ConfigurationHelper.getBoolean(value));
      } else if (HINT_CACHE_MODE.equals(hintName)) {
        applied = applyCacheModeHint(ConfigurationHelper.getCacheMode(value));
      } else if (HINT_FLUSH_MODE.equals(hintName)) {
        applied = applyFlushModeHint(ConfigurationHelper.getFlushMode(value));
      } else if (AvailableSettings.SHARED_CACHE_RETRIEVE_MODE.equals(hintName)) {
        final CacheRetrieveMode retrieveMode = (CacheRetrieveMode) value;

        CacheStoreMode storeMode =
            hints != null
                ? (CacheStoreMode) hints.get(AvailableSettings.SHARED_CACHE_STORE_MODE)
                : null;
        if (storeMode == null) {
          storeMode =
              (CacheStoreMode)
                  entityManager.getProperties().get(AvailableSettings.SHARED_CACHE_STORE_MODE);
        }
        applied = applyCacheModeHint(CacheModeHelper.interpretCacheMode(storeMode, retrieveMode));
      } else if (AvailableSettings.SHARED_CACHE_STORE_MODE.equals(hintName)) {
        final CacheStoreMode storeMode = (CacheStoreMode) value;

        CacheRetrieveMode retrieveMode =
            hints != null
                ? (CacheRetrieveMode) hints.get(AvailableSettings.SHARED_CACHE_RETRIEVE_MODE)
                : null;
        if (retrieveMode == null) {
          retrieveMode =
              (CacheRetrieveMode)
                  entityManager.getProperties().get(AvailableSettings.SHARED_CACHE_RETRIEVE_MODE);
        }
        applied = applyCacheModeHint(CacheModeHelper.interpretCacheMode(storeMode, retrieveMode));
      } else if (hintName.startsWith(AvailableSettings.ALIAS_SPECIFIC_LOCK_MODE)) {
        if (canApplyAliasSpecificLockModeHints()) {
          // extract the alias
          final String alias =
              hintName.substring(AvailableSettings.ALIAS_SPECIFIC_LOCK_MODE.length() + 1);
          // determine the LockMode
          try {
            final LockMode lockMode = LockModeTypeHelper.interpretLockMode(value);
            applyAliasSpecificLockModeHint(alias, lockMode);
          } catch (Exception e) {
            LOG.unableToDetermineLockModeValue(hintName, value);
            applied = false;
          }
        } else {
          applied = false;
        }
      } else {
        LOG.ignoringUnrecognizedQueryHint(hintName);
      }
    } catch (ClassCastException e) {
      throw new IllegalArgumentException("Value for hint");
    }

    if (applied) {
      if (hints == null) {
        hints = new HashMap<String, Object>();
      }
      hints.put(hintName, value);
    } else {
      LOG.debugf("Skipping unsupported query hint [%s]", hintName);
    }

    return this;
  }