private Query criarQueryEspecifica(Dao dao, Class entidade, List<ParametroConsulta> params) {

    String nomeQuery = entidade.getSimpleName() + ".findBy";

    for (ParametroConsulta t : params) {
      nomeQuery +=
          (String.valueOf(t.getCampo().charAt(0)).toUpperCase() + t.getCampo().substring(1));
    }

    Query query = dao.createNamedQuery(nomeQuery);

    for (ParametroConsulta t : params) {
      if (t.getTipo().equals("numero")) {
        try {
          query.setParameter(t.getCampo(), Long.valueOf(t.getValor()));
        } catch (NumberFormatException exc) {
          query.setParameter(t.getCampo(), 0L);
        }
      } else {
        query.setParameter(t.getCampo(), t.getValor());
      }
    }

    return query;
  }
  private Object consultaUnica(Dao dao, String entidade, String id, String tipo)
      throws ClassNotFoundException {

    Class klass = Class.forName(PACOTE_ENTIDADES + entidade);

    Object resultado = null;

    if (tipo.equals("numero")) {
      try {
        resultado = dao.carregar(klass, Long.valueOf(id));
      } catch (NumberFormatException exc) {
      }
    } else {
      resultado = dao.carregar(klass, id);
    }

    return resultado;
  }
  /**
   * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
   *
   * @param request servlet request
   * @param response servlet response
   * @throws ServletException if a servlet-specific error occurs
   * @throws IOException if an I/O error occurs
   */
  protected void processRequest(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {

    response.setContentType("text/json;charset=UTF-8");
    PrintWriter out = response.getWriter();

    Dao dao = DaoFactory.getDao();

    try {

      String tipoConsulta = request.getParameter("tipoConsulta");
      List<Object> dados = new ArrayList();

      String entidade = request.getParameter("entidade");
      Class classeEntidade = Class.forName(PACOTE_ENTIDADES + entidade);

      int inicio = 0;
      int quantidade = 0;
      int total = 0;
      boolean aplicarLimite = Boolean.parseBoolean(request.getParameter("aplicarLimite"));

      if (aplicarLimite) {
        inicio = Integer.parseInt(request.getParameter("start"));
        quantidade = Integer.parseInt(request.getParameter("limit"));
      }

      String id;
      String tipo;
      Object resultado;
      List<Object> resultados;

      Gson gson =
          new GsonBuilder()
              .setExclusionStrategies(new EstrategiaExclusaoJSON())
              .serializeNulls()
              .create();

      switch (tipoConsulta) {
        case "unica":
          id = request.getParameter("id");
          tipo = request.getParameter("tipo");

          resultado = consultaUnica(dao, entidade, id, tipo);

          if (resultado != null) {
            total = 1;
            dados.add(resultado);
          }

          break;

        case "completa":
          total = dao.obterQuantidadeDeRegistros(classeEntidade);

          if (aplicarLimite) {
            resultados = consultaCompletaComIntervalo(dao, classeEntidade, inicio, quantidade);
          } else {
            resultados = consultaCompleta(dao, classeEntidade);
          }

          dados.addAll(resultados);
          break;

        case "especifica":
          Type tipoLista = new TypeToken<List<ParametroConsulta>>() {}.getType();
          List<ParametroConsulta> parametros =
              gson.fromJson(request.getParameter("parametros"), tipoLista);

          if (parametros.size() == 1 && parametros.get(0).getCampo().equals("id")) {

            ParametroConsulta t = parametros.get(0);
            resultado = consultaUnica(dao, entidade, t.getValor(), t.getTipo());

            if (resultado != null) {
              total = 1;
              dados.add(resultado);
            }

          } else {

            if (aplicarLimite) {
              resultados =
                  consultaEspecificaComIntervalo(
                      dao, classeEntidade, parametros, inicio, quantidade);
              total = consultaEspecifica(dao, classeEntidade, parametros).size();
            } else {
              resultados = consultaEspecifica(dao, classeEntidade, parametros);
              total = resultados.size();
            }

            dados.addAll(resultados);
          }

          break;

        default:
          dados = new ArrayList();
          break;
      }

      StringBuilder sb = new StringBuilder();

      for (Object o : dados) {
        Uteis.atravessarConfigurandoValorPadrao(o);
      }

      sb.append("{ \"success\": true, ");
      sb.append("\"total\": ");
      sb.append(total);
      sb.append(", ");
      sb.append("\"itens\": ");
      sb.append(gson.toJson(dados));
      sb.append("}");

      out.print(sb.toString());

      dao.fecharEntityManager();

    } catch (ClassNotFoundException | HibernateException | PersistenceException exc) {

      dao.fecharEntityManager();

      out.print(Uteis.gerarJSONRetornoOperacao(exc));

    } finally {
      out.close();
    }
  }
  private List<Object> consultaCompletaComIntervalo(
      Dao dao, Class entidade, int inicio, int quantidade) throws ClassNotFoundException {

    return dao.carregarTodosNoIntervalo(entidade, inicio, quantidade);
  }
  private List<Object> consultaCompleta(Dao dao, Class entidade) throws ClassNotFoundException {

    return dao.carregarTodos(entidade);
  }