Prezados,
Tenho um sistema utilizando JSF, EJB, JPA que se conecta a um banco PostgreSql.
Agora, preciso me conectar com um outro banco PostgreSql para fazer uma carga de uns poucos dados.
Esta carga será realizada todos os dias por apenas 2 meses. Vou utilizar a anotação @Schedule para fazer esta carga de maneira automática.
Meu problema é que eu não queria fazer o mapeamento deste outro banco para não “sujar” meu sistema com algo temporário.
É possível fazer uma conexão JDBC (sem JPA) para buscar estes dados e jogá-los em meu banco que já está mapeado?
Tentei fazer isto mas dá um erro bizarro.
Obrigado,
Augusto
Conexão JPA + Conexão JDBC
7 Respostas
Qual o erro?
Quando estou fazendo a busca no banco de dados de origem, tudo vai bem até por volta de 35000 registros recuperados, neste momento ele dá o seguinte erro:
WARNING: EJB5184:A system exception occurred during an invocation on EJB AtualizacaoDadosPosMigracao, method: public void br.com.coderp.j302.carga.AtualizacaoDadosPosMigracao.atualizar()
WARNING: javax.ejb.EJBException
at com.sun.ejb.containers.BaseContainer.processSystemException(BaseContainer.java:5215)
at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:5113)
at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4901)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2045)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1994)
at com.sun.ejb.containers.BaseContainer.callEJBTimeout(BaseContainer.java:4088)
at com.sun.ejb.containers.EJBTimerService.deliverTimeout(EJBTimerService.java:1832)
at com.sun.ejb.containers.EJBTimerService.access$100(EJBTimerService.java:108)
at com.sun.ejb.containers.EJBTimerService$TaskExpiredWork.run(EJBTimerService.java:2646)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Caused by: java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.util.Arrays.copyOfRange(Arrays.java:2694)
at java.lang.String.(String.java:234)
at java.lang.StringBuilder.toString(StringBuilder.java:405)
at java.util.ResourceBundle.getObject(ResourceBundle.java:393)
at java.util.ResourceBundle.getString(ResourceBundle.java:353)
at com.sun.enterprise.server.logging.UniformLogFormatter.uniformLogFormat(UniformLogFormatter.java:336)
at com.sun.enterprise.server.logging.UniformLogFormatter.format(UniformLogFormatter.java:162)
at java.util.logging.StreamHandler.publish(StreamHandler.java:196)
at java.util.logging.ConsoleHandler.publish(ConsoleHandler.java:105)
at java.util.logging.Logger.log(Logger.java:522)
at com.sun.logging.LogDomains$1.log(LogDomains.java:372)
at java.util.logging.Logger.doLog(Logger.java:543)
at java.util.logging.Logger.logp(Logger.java:659)
at com.sun.common.util.logging.LoggingOutputStream.flush(LoggingOutputStream.java:106)
at java.io.PrintStream.write(PrintStream.java:482)
at com.sun.common.util.logging.LoggingOutputStream$LoggingPrintStream.write(LoggingOutputStream.java:337)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104)
at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)
at java.io.PrintStream.write(PrintStream.java:527)
at java.io.PrintStream.print(PrintStream.java:669)
at com.sun.common.util.logging.LoggingOutputStream$LoggingPrintStream.print(LoggingOutputStream.java:242)
at java.io.PrintStream.println(PrintStream.java:806)
at com.sun.common.util.logging.LoggingOutputStream$LoggingPrintStream.println(LoggingOutputStream.java:191)
at br.com.coderp.j302.carga.AtualizacaoDadosPosMigracao.atualizarDadosPosMigracao(AtualizacaoDadosPosMigracao.java:48)
at br.com.coderp.j302.carga.AtualizacaoDadosPosMigracao.atualizar(AtualizacaoDadosPosMigracao.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1052)
Esta é a minha classe:
package br.com.coderp.j302.carga;
...
@Stateless
public class AtualizacaoDadosPosMigracao {
static List<Guia> listaGuiaOld = new ArrayList<Guia>();
@Schedule(dayOfWeek = "*", hour = "16", minute = "33")
public void atualizar() {
try {
atualizarDados();
listarGuias();
} catch (Exception e) {
LoggerUtil.severe(this.getClass(), e);
}
}
private void atualizar() throws Exception {
try{
String driver = "org.postgresql.Driver";
String user = "admin";
String senha = "admin";
String url = "jdbc:postgresql://localhost/banco_teste";
Class.forName(driver);
Connection con = (Connection) DriverManager.getConnection(url, user, senha);
Statement stm = con.createStatement();
String query = "select * from tabela ";
ResultSet rs = stm.executeQuery(query);
int contador = 1;
Guia g = null;
while (rs.next()) {
System.out.println("contador: " + contador++);
g = new Guia();
g.setAno_Guia(rs.getLong("Ano_Guia"));
g.setNro_Guia(rs.getLong("Nro_Guia"));
...
listaGuiaOld.add(g);
}
con.close();
}catch(ClassNotFoundException e){
System.out.println("Não foi encontrada a classe de conexao com o banco: " + e.getMessage());
}catch(SQLException e){
System.out.println("Ocorreu um erro ao tentar se conectar com o banco: " + e.getMessage());
}catch(Exception e){
System.out.println("Erro geral: " + e.getMessage());
}
}
private void listarGuias() throws Exception {
int contador = 1;
for (Guia g : listaGuiaOld) {
System.out.println(contador++);
System.out.println(g.getAdquirente_Nome());
}
}
}
Esse erro ta acontecendo pq está sendo trazido muito registro do DB e a memória esta estourando.
Você precisa de todos esses registros mesmo?
Então, tenho duas situações diferentes: numa eu preciso de todos os registros em outra preciso apenas de alguns.
Nesse caso cara eu não tenho muita exp nao. Mas achei uma saída na net: http://www.devx.com/java/Article/21383/1954
http://benjchristensen.com/2008/05/27/mysql-jdbc-memory-usage-on-large-resultset/
Teria que paginar seu resultado. =/
Ambos resultados apontam como solução por esse problema.
No google eu pesquisei por: [google]resultset large data[/google].
Vamos ver se algum ninja passa por aqui e dá uma solução que se aplica melhor a essa situação.
Kra, vlw pela sua ajuda!
Vou dar uma olhada nos links que você passou e ver o que consigo fazer.
Obrigado!