Relatório de 50000 registros com Hibernate/Jasper [Resolvido]
24 respostas
D
Danilo_Alves
Boa tarde a todos!!
Preciso gerar um relatório com aproximadamente 50000 registros. Estou usando banco Oracle 9g, PL/SQL na query e a tabela consultada não tem relacionamentos.
O cache de segundo nível do hibernate está configurado da seguinte forma:
o que quer dizer com ‘nao consegue trazer os dados’?
se vc nao precisa ter todos os dados em memoria ao mesmo tempo, pode ir simplesmente pegando de pouco em pouco.
da uma procurada sobre StatelessSession e ScrollableResults. podem te ajudar…
sergio
D
Danilo_Alves
Ele literalmente não consegue, dá uma olhada no código:
Queryq=getSession().createSQLQuery(sql);if(cacheable)q.setCacheable(true);list=q.list(); //nessa linha ele fica processando eternamente
Vou dar uma pesquisada sobre StatelessSession e ScrollableResults.
Giulliano
Tenta jogar a consult numa thread separada…provavelmente ambos (JDBC e Hibernate) vão demorar muito. Não vejo necessidade de trazer 50000 registros de uma só vez…se for para alguém ler ninguém tem essa capacidade e ainda q seja para outros objetivos vc poderia dar um select count(*) from tabela…dividir o total de registro e trazer em pedaços.
D
Danilo_Alves
Com scrollable results eu consegui obter os registros e passá-los para uma collection mas agora eu tenho que mandar esta collection para um relatório que é um jasper (JRBeanDataSource). Se eu mandar a collection inteira de uma vez ocorre o famoso: java.lang.OutOfMemoryError: Java heap space.
Vou procurar alternativas… se alguém tiver alguma sugestão, por favor habilite-se.
Muito obrigado Sérgio, obrigado a todos.
qmx
vc fez o finetune da jvm ??
exemplo
1Gb de heap
java -Xmx1024GB…
danieldestro
Relatório com 50 mil registros com Hibernate e Jasper?
Será que essa não é uma solução inviável?
O tal artigo que lhe passei do JavaLobby indica que você pode usar o Hibernate para recuperar os registros de forma paginada, de forma que você não precise ficar com os 50000 registros de uma vez na memória. Ele deu um exemplo com o JasperReports, mas a maneira de fazer sugere o que deve ser feito para sua solução de relatórios.
D
Danilo_Alves
thingol:
O tal artigo que lhe passei do JavaLobby indica que você pode usar o Hibernate para recuperar os registros de forma paginada, de forma que você não precise ficar com os 50000 registros de uma vez na memória. Ele deu um exemplo com o JasperReports, mas a maneira de fazer sugere o que deve ser feito para sua solução de relatórios.
Vou ler este artigo, muito obrigado Thingol
D
Danilo_Alves
Implementei as soluções oferecidas pelo Hibernate (StatelessSession e Scrollable Results) utilizando a arquitetura sugerida no artigo. O autor propõe um acoplamento do Hibernate com o Jasper… bem interessante.
A carga dos dados e o processamento do relatório realmente ficaram mais performáticos. Mas mesmo aumentando o heap da VM, ela não aguenta um relatório desse tamanho…
Estou estudando o “virtualizador de relatórios” do Jasper, se alguém souber de mais uma alternativa por favor manifeste-se.
D
Danilo_Alves
Com o JRFileVirtualizer foi possível gerar o relatório mas vou fazer mais testes para ver se é estável.
urubatan
um relatório com 50k registros não vai ser lido por ninguem, por tanto é inútil, então não deveria existir …
a única desculpa é utiliza-lo como uma forma de arquivamento de dados (uma forma burra, mas fazer o que …)
mesmo assim, acho que deveria argumentar com o chefe, dizendo que este vai ser o relatório mais inútil do sistema
D
Danilo_Alves
Eu estou meio alheio a parte de regras de negócio desse sistema mas por se tratar de um cliente telecom, o volume de dados é fora do padrão. Segundo o responsável pelo projeto é comum relatórios desse porte ou ainda maiores neste ramo. O cara tem 10 anos de experiência de desenvolvimento em telecom… :shock:
urubatan
OK, mas ninguem vai ler este relatório todo, ou pelo menos eu acho muito pouco provável …
e se ninguem for ler, ele é inútil …
Exceto no caso de ser um demonstrativo para enviar para alguma coisa …
Acho que antes de implementar valeria primeiro perguntar se alguem vai ler esta porquera
D
Danilo_Alves
Tem razão mas como diz a turma aí: “Ordens são ordens” :-o
danieldestro
Eu lembro da minha mãe vendo relatórios de quase 100 páginas lá no banco que ela trabalhava. Isso nos anos 80.
Conferência manual? Que era esse povo vive?
fabim
urubatan:
OK, mas ninguem vai ler este relatório todo, ou pelo menos eu acho muito pouco provável …
e se ninguem for ler, ele é inútil …
Exceto no caso de ser um demonstrativo para enviar para alguma coisa …
Acho que antes de implementar valeria primeiro perguntar se alguem vai ler esta porquera :D
Com certeza ninguem vai ler. Isso todo mundo ja percebeu.
No minimo e pra efeito de arquivamento mesmo, mas nao vai ser o rapaz que esta com o problema do topico, nem eu nem vc que vai convencê-lo do contrário.
Determinadas situações nao demandam “a solução certa”, mas simplesmente o que “o cliente quer”. E se o cliente paga bem, entao nao tem discussão. Vc pode:
Ficar ai esperneando de que a solução é porca, que o cliente esta errado e perder o lugar pra outra pessoa que queira fazer a “porqueira”.
Fazer a porqueira, e embolsar grana
Eu fico com a opção 2.
D
Danilo_Alves
fabiocsi:
urubatan:
OK, mas ninguem vai ler este relatório todo, ou pelo menos eu acho muito pouco provável …
e se ninguem for ler, ele é inútil …
Exceto no caso de ser um demonstrativo para enviar para alguma coisa …
Acho que antes de implementar valeria primeiro perguntar se alguem vai ler esta porquera :D
Com certeza ninguem vai ler. Isso todo mundo ja percebeu.
No minimo e pra efeito de arquivamento mesmo, mas nao vai ser o rapaz que esta com o problema do topico, nem eu nem vc que vai convencê-lo do contrário.
Determinadas situações nao demandam “a solução certa”, mas simplesmente o que “o cliente quer”. E se o cliente paga bem, entao nao tem discussão. Vc pode:
Ficar ai esperneando de que a solução é porca, que o cliente esta errado e perder o lugar pra outra pessoa que queira fazer a “porqueira”.
Fazer a porqueira, e embolsar grana
Eu fico com a opção 2.
Exatamente.
urubatan
ja que o cara não vai nem tentar dizer pro cliente que ele ta botando dinheiro fora,
então sugiro para este relatório tirar o hibernate da jogada e fazer via JDBC mesmo, desta forma mantendo apenas um registro na memória por vez.
e não jogar tudo em uma collection antes de passar para o jasper e sim usar o jrresultsetdatasource …
Mas ainda acho que se ele simplesmente fizer isto ele não vai estar fazendo nada mais do que a obrigação dele, agora se ele levantar e questionar o gerente/cliente/qualquer um, questionar se o relatório vai realmente ser lido, se realmente vale a pena a implementação.
ai ele vai em pouco tempo, merecer ganhar mais do que ganha hoje.
fabim
urubatan:
ja que o cara não vai nem tentar dizer pro cliente que ele ta botando dinheiro fora,
então sugiro para este relatório tirar o hibernate da jogada e fazer via JDBC mesmo, desta forma mantendo apenas um registro na memória por vez.
e não jogar tudo em uma collection antes de passar para o jasper e sim usar o jrresultsetdatasource …
Mas ainda acho que se ele simplesmente fizer isto ele não vai estar fazendo nada mais do que a obrigação dele, agora se ele levantar e questionar o gerente/cliente/qualquer um, questionar se o relatório vai realmente ser lido, se realmente vale a pena a implementação.
ai ele vai em pouco tempo, merecer ganhar mais do que ganha hoje.
Se existe uma maneira melhor, é mais que obrigação contra-argumentar a solução.
Mas acredite em mim: existem clientes que, sem nem ao menos saber o que é Java, ou Ruby, ou Banco de Dados, entendem mais de OO do que Martin Fowler.
E ai de vc se disser que não.
D
Danilo_Alves
urubatan:
ja que o cara não vai nem tentar dizer pro cliente que ele ta botando dinheiro fora,
então sugiro para este relatório tirar o hibernate da jogada e fazer via JDBC mesmo, desta forma mantendo apenas um registro na memória por vez.
e não jogar tudo em uma collection antes de passar para o jasper e sim usar o jrresultsetdatasource …
Mas ainda acho que se ele simplesmente fizer isto ele não vai estar fazendo nada mais do que a obrigação dele, agora se ele levantar e questionar o gerente/cliente/qualquer um, questionar se o relatório vai realmente ser lido, se realmente vale a pena a implementação.
ai ele vai em pouco tempo, merecer ganhar mais do que ganha hoje.
A forma que eu implementei não carrega todos os registros na memória pois adotei esta arquitetura:
Resumindo, você acopla o hibernate com o jasper implementando seu próprio JRBeanDataSource. E com ajuda do scrollable results do Hibernate os registros são carregados um a um conforme o Jasper preenche o relatório, evitando absolutamente qualquer estouro de memória (graças ao JRVirtualizer também).