Acessando o retorno de uma NativeQuery não mapeada com EclipseLink [RESOLVIDO] :)

Pessoal… sem meias palavras:

Query query = entityManager.createNativeQuery("SELECT C.TIPO AS TIPO, SUM (C.VAL_JAN) AS TOTAL_JAN, SUM (C.VAL_FEV) AS TOTAL_FEV, SUM (C.VAL_MAR) AS TOTAL_MAR, SUM (C.VAL_ABR) AS TOTAL_ABR, SUM (C.VAL_MAI) AS TOTAL_MAI, SUM (C.VAL_JUN) AS TOTAL_JUN, SUM (C.VAL_JUL) AS TOTAL_JUL, SUM (C.VAL_AGO) AS TOTAL_AGO, SUM (C.VAL_SET) AS TOTAL_SET, SUM (C.VAL_OUT) AS TOTAL_OUT, SUM (C.VAL_NOV) AS TOTAL_NOV, SUM (C.VAL_DEZ) AS TOTAL_DEZ"
                + " FROM CONTAS C WHERE C.ATIVIDADE_ID = ? GROUP BY C.TIPO ORDER BY C.TIPO");
        query.setParameter(1, MenuView._this.getAtividadeSelecionID());
        List retornoQuery = query.getResultList();

Até ai tudo bem, agora, como percorrer este “retornoQuery”? já tentei de muitas formas mas todas deram errado.
Obs: não tenho nenhuma classe para mapear este retorno, até porque é um resultado vindo de um agrupamento( GROUP BY ), senão seria mamão com açúcar!

Conto com a colaboração dos experts em eclipseLink e por favor, sem repostas fúteis só para ganhar pontos para subir de nível no fórum!

Abrçs…

E dae root_, blz?

Se eu não me engano essa consulta retorna uma List.
Faz cast pro tipo que vc espera e já era!!!

[]'s

acho que esse tópico te ajuda:

http://www.guj.com.br/java/124559-agrupamento-max-e-sum-com-jpa

E retorna um array de objetos mesmo.

Completando…

No seu caso retorna um List<Object[]>.
Existe a possibilidade de vc criar um objeto não mapeado e usá-lo.

List

e na consulta…

Query query = entityManager.createNativeQuery("SELECT new seupacote.Resultado(parametro1,parametro2) from …);

sua classe Resultado tem que ter um construtor com os parametros do select…

[]´s

[quote=juliannoms]E dae root_, blz?

Se eu não me engano essa consulta retorna uma List.
Faz cast pro tipo que vc espera e já era!!!

[]'s[/quote]

Mano… cast concerteza foi a primeira das tentativas…

[quote=evefuji]acho que esse tópico te ajuda:

http://www.guj.com.br/java/124559-agrupamento-max-e-sum-com-jpa

E retorna um array de objetos mesmo.[/quote]

ever…
Melhor dica… caso seja algo bem random… até porque a classe com a qual eu faria o CAST não tem anotação JPA…
então… salve ao método unwarp do entityManager.

segue a solução:

//nem preciso explicar muito né... ele me retorna um Connection. simples assim eu volto ao velho Statements...
Connection conn =  entityManager.unwrap(java.sql.Connection.class);
        try {
            Statement st = conn.createStatement();
            ResultSet rs = st.executeQuery( "SELECT C.TIPO AS TIPO, SUM (C.VAL_JAN) AS TOTAL_JAN, SUM (C.VAL_FEV) AS TOTAL_FEV, SUM (C.VAL_MAR) AS TOTAL_MAR, SUM (C.VAL_ABR) AS TOTAL_ABR, SUM (C.VAL_MAI) AS TOTAL_MAI, SUM (C.VAL_JUN) AS TOTAL_JUN, SUM (C.VAL_JUL) AS TOTAL_JUL, SUM (C.VAL_AGO) AS TOTAL_AGO, SUM (C.VAL_SET) AS TOTAL_SET, SUM (C.VAL_OUT) AS TOTAL_OUT, SUM (C.VAL_NOV) AS TOTAL_NOV, SUM (C.VAL_DEZ) AS TOTAL_DEZ"
                + " FROM CONTAS C WHERE C.ATIVIDADE_ID = '" +MenuView._this.getAtividadeSelecionID()+"' GROUP BY C.TIPO ORDER BY C.TIPO");
            while(rs.next()) {
                TotaisMesConta obj = new TotaisMesConta();
                obj.setDescrResult(rs.getString("TIPO"));
                obj.setTotalJan(rs.getBigDecimal("TOTAL_JAN"));
                obj.setTotalFev(rs.getBigDecimal("TOTAL_FEV"));
                obj.setTotalMar(rs.getBigDecimal("TOTAL_MAR"));
                obj.setTotalAbr(rs.getBigDecimal("TOTAL_ABR"));
                obj.setTotalMai(rs.getBigDecimal("TOTAL_MAI"));
                obj.setTotalJun(rs.getBigDecimal("TOTAL_JUN"));
                obj.setTotalJul(rs.getBigDecimal("TOTAL_JUL"));
                obj.setTotalAgo(rs.getBigDecimal("TOTAL_AGO"));
                obj.setTotalSet(rs.getBigDecimal("TOTAL_SET"));
                obj.setTotalOut(rs.getBigDecimal("TOTAL_OUT"));
                obj.setTotalNov(rs.getBigDecimal("TOTAL_NOV"));
                obj.setTotalDez(rs.getBigDecimal("TOTAL_DEZ"));
                list.add(obj);
            }
        } catch (SQLException ex) {
            Logger.getLogger(MovFinanceiraView.class.getName()).log(Level.SEVERE, null, ex);
        }

Dai pra frente simples… que foi a criação de um relatório Gráfico com jasperreports. passando uma JrBeanDataSource como parâmetro para o relatório
Alias… a minha solução.

Obrigado pelas colaborações…

Gostei do método unwarp, vou lembrar para quando eu estiver precisando.

Edit: Não sabia que não tinha mapeada a tabela em uma classe. Mas gostei da sua solução.

Cara, eu não conhecia essa solução que vc deu. Pode ser interessante pra alguns casos sim, mas não pra esse!

//vc pega aquele array de objetos retornados pelo JPA e faz um foreach
for (Object[] objeto : resultado){
     Double soma1 = (Double) objeto[0]; //antes disso vc faz as verificações necessárias para que funcione o cast, certo?
     ... //faz o mesmo no array todo...
}

Porém, o caso é criar um relatório…

//cria uma classe para o seu relatório (essa classe não é mapeada)
public class RetornoJPARel{

    public RetornoJPARel(Double soma1, Double soma2, String texto1){
          this.soma1 = soma1;
          this.soma2 = soma2;
          this.texto1 = texto1;
    }
    private Double soma1;
    private Double soma2;
    private String texto1;

    //getters and setters
}

//aí vc faz um método que retorne um List<RetornoJPARel>

public List<RetornoJPARel> getListaParaORelatorio(Entity paramentro){ 
   String jpql = "select NEW RetornoJPARel( sum(e.valor1), sum(e.valor2), e.qquercoisa) from Entity e where e = :parametro; ";
   //aqui vc faz todos os passos para entitymanager e setar parametros e tals
   //depois vc retorna a lista
   return query.getResultList();
}

Eu acho que dessa forma fica mais “bonito” de se fazer…
Se vc tá usando jasper, pode fazer um método stático que retorne essa lista dentro de um JRBeanCollection e chamar o método do relatório…

Espero ter ajudado!
Gostei da dica do unwarp.

T+

juliannoms … ótima idéia… ao invéz de eu fazer um cast para o objeto Bean em questão, apenas pegar um array[] mesmo e depois ir realizando os casts para os tipos dos campos do Bean…
Excelente amigo! tb funciona!

Pessoal, tive este mesmo problema e resolvi da seguinte porma:

EntityManagerFactory factory = Persistence.createEntityManagerFactory(“Projeto”);
EntityManager manager = factory.createEntityManager();
Query query = manager.createQuery(“select t from Usuario as t where t.senha = :paramSenha and t.login = :paramLogin”);
query.setParameter(“paramLogin”, “padrao”);
query.setParameter(“paramSenha”, “padrao”);

@SuppressWarnings(“unchecked”)
List lista = query.getResultList();

for (Usuario t : lista) {
System.out.println(t.getLogin());
}
manager.close();