public <T> TypedQuery<T> createQuery(String jpaqlString, Class<T> resultClass) {
   try {
     org.hibernate.Query hqlQuery = getSession().createQuery(jpaqlString);
     if (hqlQuery.getReturnTypes().length != 1) {
       throw new IllegalArgumentException(
           "Cannot create TypedQuery for query with more than one return");
     }
     if (!resultClass.isAssignableFrom(hqlQuery.getReturnTypes()[0].getReturnedClass())) {
       throw new IllegalArgumentException(
           "Type specified for TypedQuery ["
               + resultClass.getName()
               + "] is incompatible with query return type ["
               + hqlQuery.getReturnTypes()[0].getReturnedClass()
               + "]");
     }
     return new QueryImpl<T>(hqlQuery, this);
   } catch (HibernateException he) {
     throw convert(he);
   }
 }
  public <T> TypedQuery<T> createQuery(
      String jpaqlString, Class<T> resultClass, Selection selection, Options options) {
    try {
      org.hibernate.Query hqlQuery = getSession().createQuery(jpaqlString);

      if (options.getValueHandlers() == null) {
        options.getResultMetadataValidator().validate(hqlQuery.getReturnTypes());
      }

      // determine if we need a result transformer
      List tupleElements =
          Tuple.class.equals(resultClass)
              ? ((CompoundSelectionImpl<Tuple>) selection).getCompoundSelectionItems()
              : null;
      if (options.getValueHandlers() != null || tupleElements != null) {
        hqlQuery.setResultTransformer(
            new CriteriaQueryTransformer(options.getValueHandlers(), tupleElements));
      }
      return new QueryImpl<T>(hqlQuery, this, options.getNamedParameterExplicitTypes());
    } catch (HibernateException he) {
      throw convert(he);
    }
  }
 /**
  * Returns the return types of the HQL query.
  *
  * @return the return types of the HQL query
  */
 public Type[] getReturnTypes() {
   return query.getReturnTypes();
 }
  public <T> TypedQuery<T> createNamedQuery(String name, Class<T> resultClass) {
    try {
      /*
       * Get the named query.
       * If the named query is a SQL query, get the expected returned type from the query definition
       * or its associated result set mapping
       * If the named query is a HQL query, use getReturnType()
       */
      org.hibernate.Query namedQuery = getSession().getNamedQuery(name);
      // TODO clean this up to avoid downcasting
      final SessionFactoryImplementor factoryImplementor =
          (SessionFactoryImplementor) entityManagerFactory.getSessionFactory();
      final NamedSQLQueryDefinition queryDefinition = factoryImplementor.getNamedSQLQuery(name);
      try {
        if (queryDefinition != null) {
          Class<?> actualReturnedClass;

          final NativeSQLQueryReturn[] queryReturns;
          if (queryDefinition.getQueryReturns() != null) {
            queryReturns = queryDefinition.getQueryReturns();
          } else if (queryDefinition.getResultSetRef() != null) {
            final ResultSetMappingDefinition rsMapping =
                factoryImplementor.getResultSetMapping(queryDefinition.getResultSetRef());
            queryReturns = rsMapping.getQueryReturns();
          } else {
            throw new AssertionFailure(
                "Unsupported named query model. Please report the bug in Hibernate EntityManager");
          }
          if (queryReturns.length > 1) {
            throw new IllegalArgumentException(
                "Cannot create TypedQuery for query with more than one return");
          }
          final NativeSQLQueryReturn nativeSQLQueryReturn = queryReturns[0];
          if (nativeSQLQueryReturn instanceof NativeSQLQueryRootReturn) {
            final String entityClassName =
                ((NativeSQLQueryRootReturn) nativeSQLQueryReturn).getReturnEntityName();
            try {
              actualReturnedClass =
                  ReflectHelper.classForName(entityClassName, AbstractEntityManagerImpl.class);
            } catch (ClassNotFoundException e) {
              throw new AssertionFailure(
                  "Unable to instantiate class declared on named native query: "
                      + name
                      + " "
                      + entityClassName);
            }
            if (!resultClass.isAssignableFrom(actualReturnedClass)) {
              throw buildIncompatibleException(resultClass, actualReturnedClass);
            }
          } else {
            // TODO support other NativeSQLQueryReturn type. For now let it go.
          }
        } else {
          if (namedQuery.getReturnTypes().length != 1) {
            throw new IllegalArgumentException(
                "Cannot create TypedQuery for query with more than one return");
          }
          if (!resultClass.isAssignableFrom(namedQuery.getReturnTypes()[0].getReturnedClass())) {
            throw buildIncompatibleException(
                resultClass, namedQuery.getReturnTypes()[0].getReturnedClass());
          }
        }
        return new QueryImpl<T>(namedQuery, this);
      } catch (HibernateException he) {
        throw convert(he);
      }
    } catch (MappingException e) {
      throw new IllegalArgumentException("Named query not found: " + name);
    }
  }