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

Gerar relatorio com slq padrão JSF/JPA

Olá pessoal,

Estou com problemas no meu projeto. Estou criando uma ferramenta de registro de tickets com JSF e JPA. Tentei utilizar o JRDataSource igual na aula, porém não tive sucesso, e como estou usando JSF não consegui implementar o codigo da aula no meu projeto. Minha dúvida é a seguinte, o relatório que eu fiz no JasperStudio está funcionando perfeitamente aparece os dados certinho com a conexão direto do banco, teria como eu passar esse relatório com essa conexão pra minha aplicação java WEB quando for chamado só executar o relatorio com a consulta que ele ja tem, sem ter q passar uma Lista?

SQL utilizado no relatório:

select t.id, pt.codigo_planta, ft.nome, prt.nome, t.titulo, t.tipo,t.status from ticket t
inner join fornecedor ft on (t.idfornecedor = ft.ID)
inner join planta pt on (t.idplanta = pt.ID)
inner join projeto prt on (t.idprojeto = prt.ID)
where t.`status` in ('Working','Waiting On User','Waiting On External')
union 
select tc.id , p.codigo_planta, f.nome, pr.nome, tc.titulo, tc.tipo,tc.status from tabelach tc
inner join fornecedor f on (tc.idfornecedor = f.ID)
inner join planta p on (tc.idplanta = p.ID)
inner join projeto pr on (tc.idprojeto = pr.ID)
where tc.`status` in ('Waiting Approval','Waiting On User','Waiting On External','Working')

Nesse caso eu não precisaria submeter nada e nao passar nenhum parametro porque esse meu relatório sempre vai ter o mesmo critério de busca.

Não consegui colocar esses dados numa Lista porque aparentemente o JPA nao aceita a clausula UNION.

4 respostas

Opa, eu não manjo de jasper, mas pensando na jpa, você pode usar o método createSqlQuery e passar seu sql direto. Ele vai te retornar uma Object[][], uma matriz. Cada linha da matriz vai ter as informações do seu select... Aí você pode transformar isso numa lista.

Olá Alberto,

Testarei sua sugestão assim que chegar em casa. Obrigado!

Olá Alberto,

Não consegui achar esse metodo 'createSqlQuery', achei o metodo createNativeQuery. Segue como eu fiz:

public List<Ticket> getReportDia() {
        List<Ticket> report;
        report = em.createNativeQuery("select t.ID, pt.codigo_planta, ft.nome, prt.nome, t.titulo, t.tipo, t.status from ticket t "
                + "join fornecedor ft on (t.idfornecedor = ft.ID) "
                + "join planta pt on (t.idplanta = pt.ID) "
                + "join projeto prt on (t.idprojeto = prt.id) "
                + "where t.status in ('Working','Waiting On User','Waiting On External') "
                + "union "
                + "select tc.id, p.codigo_planta, f.nome,pr.nome, tc.titulo, tc.tipo, tc.status from tabelach tc "
                + "join fornecedor f on (tc.idfornecedor = f.id) "
                + "join planta p on (tc.idplanta = p.id) "
                + "join projeto pr on (tc.idprojeto = pr.id) "
                + "where tc.status in ('Waiting Approval','Waiting On User','Waiting On External','Working')").getResultList();
        return report;

Aparentemente esse select não dá erro, depurei o programa e vi que ele retornava 2 registros (quantidade que tem no BD), porém nao consegui utiliza-lo no report. Nesse caso, como eu tenho 2 classe, ta correto ali em cima onde eu coloco uma list de Ticket pra receber valores da minha tabela Ticket e da Tabelach? Quanto ao meu report, ele está saindo todo em branco, nao pega nem os textos estáticos que coloquei no relatório. Poderias validar meu código que gera o relatório? nao sei se está totalmente correto :/

 @PostConstruct
    public void init(){
        getServicosInicial();
    }

 public void gerarRelatorio() {
        ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
        ServletContext context = (ServletContext) externalContext.getContext();
        String arquivo = context.getRealPath("/WEB-INF/report/TestandoA4.jasper");
        JRDataSource jrds = new JRBeanCollectionDataSource(pdf);  
        gerarRelatorioWeb(jrds, null, arquivo);   

    }

    private void gerarRelatorioWeb(JRDataSource jrds, Map<String, Object> parametros, String arquivo) {
        ServletOutputStream servletOutputStream = null;
        FacesContext context = FacesContext.getCurrentInstance();
        HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();

        try {
            servletOutputStream = response.getOutputStream();
            JasperRunManager.runReportToPdfStream(new FileInputStream(new File(arquivo)), response.getOutputStream(), parametros, jrds);
            response.setContentType("application/pdf");
            servletOutputStream.flush();
            servletOutputStream.close();
            context.renderResponse();
            context.responseComplete();
        } catch (Exception e) {
            e.printStackTrace();

        }
    }   

    private void getServicosInicial() {
        this.pdf = toRepository.getReportDia();
    }

Obrigado!

solução!

Opa, do código que gera o relatório eu não tenho muito domínio, vou tentar achar uma ajuda :). em relação a query, acho dificil que já venha com seu objeto Ticket montado, você chegou a testar o estado dos objetos retornados?

Como tem um monte de campo ali, para mim o retorno seria algo como List... o size da sua lista pode ser 2, só que dois arrays :). E aí cada posição do array tem a informação do select, exatamente na mesma ordem.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software