Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

Não entendi o porque do Full Qualified Name na query

Neste ponto: "select new br.com.alura.jpa.modelo.MediaComData(avg(m.valor), day(m.data), month(m.data)) from Movimentacao m group by day(m.data), month(m.data), year(m.data)";

public List<MediaComData> getMediaDiariaDasMovimentacoes() {

        String jpql = "select new br.com.alura.jpa.modelo.MediaComData(avg(m.valor), day(m.data), month(m.data)) from Movimentacao m group by day(m.data), month(m.data), year(m.data)";

        TypedQuery<MediaComData> query = em.createQuery(jpql, MediaComData.class);

        return query.getResultList();

    }
4 respostas

Fala, Thales. Tudo bem contigo?

Tem um livro de Thorben Janssen (em inglês) qua aborda a sua dúvida em um tópico bem curto chamado Constructor references. Segue abaixo o trecho do porque de usarmos o Full Qualified Named

"As referências do construtor são uma boa projeção para casos de uso somente leitura. Eles são mais confortáveis ​​de usar do que projeções de escalar e evitam a sobrecarga de entidades gerenciadas.

JPQL permite definir uma chamada de construtor na cláusula SELECT. Você só precisa fornecer o nome da classe totalmente qualificado e especificar os parâmetros do construtor de um construtor existente. Semelhante à projeção de entidade, o Hibernate gera uma consulta SQL que retorna as colunas do banco de dados necessárias e usa a referência do construtor para instanciar um novo objeto para cada registro no conjunto de resultados."

Veja que após incluirmos o @NamedQueryna Classe Movimentacao

@NamedQuery(name="mediaDiariaMovimentacoes", query="select new br.com.alura.jpa.modelo.MediaComData(avg(m.valor), day(m.data), month(m.data))" +
        "from Movimentacao m group by day(m.data), month(m.data), year(m.data)")

não é mais necessário chamar novamente dentro do método. Basta invocarmos o mediaDiariaMovimentacoesdo @NamedQuery

    public List<MediaComData> getMediaDiariaDasMovimentacoes() {
        TypedQuery<MediaComData> query = em.createNamedQuery("mediaDiariaMovimentacoes", MediaComData.class);
        return query.getResultList();
    }

Espero ter contribuído, Thales!

Um abraço e bons estudos!

Entendi Cassio, porém ao realizar esse mesmo procedimento utilizando a namedQuery para a movimentação de soma, não precisei utilizar o FQN e mesmo assim funcionou:

package br.com.alura.jpa.modelo;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQuery;

@NamedQuery(name = "soma", query = "select sum(m.valor) from Movimentacao m")
@NamedQuery(name = "media", query = "select new br.com.alura.jpa.modelo.MediaComData(avg(m.valor), day(m.data), month(m.data)) from Movimentacao m group by day(m.data), month(m.data), year(m.data)")
solução!

SUM é uma função intrínseca do SQL, por isso você não precisa dar uma referência para ela...

Agora MediaComData não existe no universo SQL, então você precisa "ensinar" para o seu código onde encontrá-la.

Entendido Cristiano, muito obrigado!