Conexão JPA + Conexão JDBC

7 respostas
apferreira

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

7 Respostas

Hebert_Coelho

Qual o erro?

apferreira

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)
apferreira

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());
        }
    }

}
Hebert_Coelho

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?

apferreira

Então, tenho duas situações diferentes: numa eu preciso de todos os registros em outra preciso apenas de alguns.

Hebert_Coelho

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.

apferreira

Kra, vlw pela sua ajuda!
Vou dar uma olhada nos links que você passou e ver o que consigo fazer.
Obrigado!

Criado 3 de maio de 2012
Ultima resposta 3 de mai. de 2012
Respostas 7
Participantes 2