/**
   * 根据分页请求参数与Query获取分页请求对象
   *
   * @param request 分页请求参数对象
   * @param query Hibernate Query
   * @return {@link Page}
   */
  public <X> Page<X> findPage(PageRequest request, Query query) {
    Page<X> page = new Page<X>(request);

    if (request == null) {
      return page;
    }

    AbstractQueryImpl impl = (AbstractQueryImpl) query;

    String queryString = setPageRequestToHql(impl.getQueryString(), request);
    ReflectionUtils.setFieldValue(impl, "queryString", queryString);

    if (request.isCountTotal()) {
      long totalCount = 0;

      if (impl.hasNamedParameters()) {
        Map<String, TypedValue> map = ReflectionUtils.getFieldValue(impl, "namedParameters");
        Map<String, Object> values = new HashMap<String, Object>();

        for (Map.Entry<String, TypedValue> entry : map.entrySet()) {
          values.put(entry.getKey(), entry.getValue().getValue());
        }

        totalCount = countHqlResult(impl.getQueryString(), values);

      } else {
        List<Object> values = ReflectionUtils.invokeGetter(impl, "values");
        totalCount = countHqlResult(impl.getQueryString(), values.toArray());
      }

      page.setTotalItems(totalCount);
    }

    impl.setFirstResult(request.getOffset());
    impl.setMaxResults(request.getPageSize());

    List result = impl.list();
    page.setResult(result);

    return page;
  }
  /**
   * 执行count查询获得本次Criteria查询所能获得的对象总数.
   *
   * @param c Criteria对象
   * @return long
   */
  protected long countCriteriaResult(Criteria c) {
    CriteriaImpl impl = (CriteriaImpl) c;

    // 先把Projection、ResultTransformer、OrderBy取出来,清空三者后再执行Count操作
    Projection projection = impl.getProjection();
    ResultTransformer transformer = impl.getResultTransformer();

    List<CriteriaImpl.OrderEntry> orderEntries = null;
    try {
      orderEntries = (List) ReflectionUtils.getFieldValue(impl, "orderEntries");
      ReflectionUtils.setFieldValue(impl, "orderEntries", new ArrayList());
    } catch (Exception e) {
      e.printStackTrace();
    }

    // 执行Count查询
    Long totalCountObject = (Long) c.setProjection(Projections.rowCount()).uniqueResult();
    long totalCount = (totalCountObject != null) ? totalCountObject : 0;

    // 将之前的Projection,ResultTransformer和OrderBy条件重新设回去
    c.setProjection(projection);

    if (projection == null) {
      c.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
    }
    if (transformer != null) {
      c.setResultTransformer(transformer);
    }

    try {
      ReflectionUtils.setFieldValue(impl, "orderEntries", orderEntries);
    } catch (Exception e) {
      e.printStackTrace();
    }

    return totalCount;
  }