Erro ao rodar a query em hql

8 respostas
A

Pessoal estou com problemas em rodar essa busca ranqueada por preço.

@Query("select f.id, f.nome, f.marca, f.modelo, f.dataFabricacao, f.consumoMedioCombustivelDentroDaCidade, f.consumoMedioCombustivelEmRodovias, f.atualizacao," +
        "((:consumoMedioCombustivelDentroDaCidade / f.consumoMedioCombustivelDentroDaCidade) + (:consumoMedioCombustivelEmRodovias / f.consumoMedioCombustivelEmRodovias)) * :valorGasolina) as valor)" +
        "FROM Frota f " +
        "ORDER BY valor ")
List<Frota> findByPrecoEDistancia(
        @Param("valorGasolina") Double preco,
        @Param("consumoMedioCombustivelDentroDaCidade") Double consumoMedioCombustivelDentroDaCidade,
        @Param("consumoMedioCombustivelEmRodovias") Double consumoMedioCombustivelEmRodovias);

o log está dizendo que tem um erro de sintaxe no hql, mas não estou conseguindo identificar.

8 Respostas

Lucas_Camara

Acho que vc está complicando esse HQL sem precisar. Vc pode tirar essa complexidade da consulta e colocar na entidade Frota.

DICA: Tu pode encurtar essas variaveis para ficar um pouco mais confortavel de ler o código:

  • consumoMedioCombustivelDentroDaCidade => consumoMedioCombustivelCidade
  • consumoMedioCombustivelEmRodovias => consumoMedioCombustivelRodovia

Defina um método na classe Frota que irá fazer o cálculo:

public Double calcular(
  Double consumoMedioCombustivelCidade, 
  Double consumoMedioCombustivelRodovia, 
  Double valorGasolina
) {
  return (
    (consumoMedioCombustivelCidade / this.consumoMedioCombustivelCidade) + 
    (consumoMedioCombustivelRodovia / this.consumoMedioCombustivelRodovia)
  ) * valorGasolina;
}

E ao recuperar as frotas, vc pode chamar o método que calcula:

// Como não tem condição no **where**, use o findAll do repository:
List<Frota> frotas = frotaRepository.findAll();

List<Double> valoresCalculados = frotas.stream()
  .map(f -> f.calcular(consumoMedioCombustivelCidade, consumoMedioCombustivelRodovia, valorGasolina))
  .collect(Collectors.toList());
A

Obrigado, mas me tire mais uma dúvida, como eu faria para retornar com esse valor total no meu método?
pois teria que retornar todos os valores mais esse valor total e que busca seja ranqueada pelo valor mais alto.

A

Teria que retornar uma Lista de Frota no service.

Lucas_Camara

Não sei se entendi direito. Mas do jeito que exemplifiquei, vc bastaria recuperar as frotas assim no seu service:

List<Frota> frotas = frotaRepository.findAll();

e retornar a lista.

E caso seja necessário realizar o cálculo para alguma frota, basta chamar o método calcular da classe Frota.

A

é isso mesmo, porem a busca que eu estava tentando fazer no hql teria obrigatoriamente trazer todos os registros da fronta, juntamente com método calculado e ranqueado pelo valor maior.
seria isso:
Criar uma API Rest de cadastro de veículos para armazenar os veículos utilizados pela
empresa. O cadastro deverá conter os seguintes dados:

  • Nome
  • Marca
  • Modelo
  • Data de fabricação
  • Consumo Médio de combustível dentro de cidade (KM/L)
  • Consumo Médio de combustível em rodovias (KM/L)

Criar uma API para realizar o cálculo de previsão de gastos.

Deverá receber como parâmetro as seguintes informações:

  • Preço da gasolina R$
  • Total de km que será percorrido dentro da cidade
  • Total de km que será percorrido em rodovias

O retorno deverá ser uma lista ranqueada dos veículos da empresa levando em
consideração o valor gasto com combustível.O retorno deverá ter os seguintes dados:

  • Nome
  • Marca
  • Modelo
  • Ano
  • Quantidade de combustível gasto
  • Valor total gasto com combustível
Lucas_Camara

Certo. O que achei errado era a forma como vc estava fazendo o calculo.

Isso o findAll resolve:

List<Frota> frotas = frotaRepository.findAll();

O método que fiz (calcular) resolve parte desse problema. Faltou a parte da ordenação pelo maior valor, mas isso é fácil de resolver.

Lucas_Camara

Tentei implementar o cenário que vc está tentando fazer:

FrotaRanqueada

public class FrotaRanqueada {
  private Frota frota;
  private Double valorGastoCombustivel;

  public FrotaRanqueada(
    Frota frota,
    Double consumoMedioCombustivelCidade,
    Double consumoMedioCombustivelRodovia,
    Double valorGasolina
  ) {
    this.frota = frota;
    this.valorGastoCombustivel = frota.calcular(
      consumoMedioCombustivelCidade,
      consumoMedioCombustivelRodovia,
      valorGasolina
    );
  }

  // getters
}

FrotaService

@Service
public class FrotaService {

  private FrotaRepository frotaRepository;

  public FrotaService(FrotaRepository frotaRepository) {
    this.frotaRepository = frotaRepository;
  }
  
  public List<FrotaRanqueada> getFrotasRanqueadas(
    Double consumoMedioCombustivelCidade,
    Double consumoMedioCombustivelRodovia,
    Double valorGasolina
  ) {
    List<Frota> frotas = frotaRepository.findAll();

    List<FrotaRanqueada> frotasRanqueadas = frotas.stream()
      .map(f -> new FrotaRanqueada(
        f, 
        consumoMedioCombustivelCidade, 
        consumoMedioCombustivelRodovia, 
        valorGasolina
      )
    ).collect(Collectors.toList());
  }
}
A

Top demais.
Obrigado.

Criado 30 de outubro de 2021
Ultima resposta 12 de nov. de 2021
Respostas 8
Participantes 2