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

JPA2: Aula - Melhorando e organizando as queries (AVG e SUM)

Na aula 07 de JPA 2 é apresentado funções por agregação, ex, AVG e SUM. Foi exemplificado o uso isolado.

E se eu quisesse exibir as contas com a média ou a soma das movimentações, ex:

sql select c.titular, c.banco, avg(m.valor) from conta c inner join movimentacao m

jpql select c, sum(m) from Conta c join c.movimentacoes

Algo do tipo, é possível ?

2 respostas
solução!

Olá Diego

A Sql que você postou na pergunta é um sql que depende do banco de dados que está sendo utilizado. Ela funciona no MySQL, mas não no SQLServer, por exemplo.

Quando agrupamos resultados de queries, só podemos devolver no select o resultado de uma função agregada (sum, min, max ou avg) ou um campo do group by. Então para que a sua query funcione em qualquer banco de dados, precisamos utilizar o seguinte código:

select c.titular, c.banco, avg(m.valor) from conta c inner join movimentacao m group by c.titular, c.banco

No jpql, precisamos obedecer exatamente a mesma restrição da sql, porém trabalhando com Entidades ao invés de tabelas do banco de dados:

select c.titular, c.banco, sum(m.valor) from Conta c join c.movimentacoes m group by c.titular, c.banco

Mas repare que essa query devolverá três valores, o titular (String), o banco (possivelmente String) e a soma do valor das movimentações (BigDecimal, Double ou Float). Quando executamos essa query pelo entity manager, a jpa nos devolve um List<Object[]>.

String jpql = "select c.titular, c.banco, sum(m.valor) from Conta c join c.movimentacoes m group by c.titular, c.banco";
Query query = manager.createQuery(jpql);
List<Object[]> resultado = (List<Object[]>) query.getResultList();
for(Object[] linha in resultado){
   String titular = (String) linha[0];
   String banco = (String) linha[1];
   BigDecimal soma = (BigDecimal) linha[2];

   // utiliza os valores devolvidos da query.
}

Ao invés de utilizar a List<Object[]>, podemos utilizar o constructor expression (http://docs.oracle.com/cd/E24329_01/apirefs.1211/e24396/ejb3_langref.html#ejb3_langref_constructor) da jpql para transformar o tipo devolvido pela query.

Olá Diego

A sua dúvida foi resolvida?