JPA - too many clients already

Oi pessoal!

Estou utilizando o JPA e alguma vezes estou recebendo o seguinte erro:

[quote]Exception in thread “Thread-0” Local Exception Stack:
Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2006.4 (Build 060412)): oracle.toplink.essentials.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: FATAL: sorry, too many clients alreadyError Code: 0 [/quote]

Para criar o ManagerFactory estou fazendo assim

[code]public class JPAConexao {

protected static EntityManagerFactory emf;

 public static EntityManagerFactory getFactory (){
    if (emf == null)
    {
        emf = Persistence.createEntityManagerFactory("BancoPU");  
    }
    return emf;
}

}[/code]

E nos metodos onde acesso o banco crio o EntityManager e dou close, olha um exemplo

[code]public Estrutura localiza(int id ) throws PersistenceException {

    EntityManager manager = JPAConexao.getFactory().createEntityManager();
    try{
        Estrutura e= manager.find(Estrutura.class,id);
        return e;
    } catch(PersistenceException pe) {
        pe.printStackTrace();
        return null;
    } catch(Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        manager.close();
    }
    
}[/code]

O que esta errado??? :roll:
O que esta faltando???

Obrigada!

Você não deveria usar o EntityManager via Injection? E deixar o container gerenciar a vida do EM para você?

E como eu faço isso???

[code]@Stateless
public class SeuSessionBeanImpl implements SeuSessionBean {
@PersistenceContext
private EntityManager em;

// …
}[/code]

Vc diz fazer isso???

[code]public class EstruturaDAO {

 @PersistenceContext
private EntityManager em;

public EstruturaDAO() {
}

public Estrutura localiza(int id ) throws PersistenceException {
    
    try{
        Estrutura p= em.find(Estrutura.class,id);
        return p;
    } catch(PersistenceException pe) {
        pe.printStackTrace();
        return null;
    } catch(Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        em.close();
    }
    
}[/code]

Mas e o EntityManagerFactory ???

Obrigada!

Se tu estiver usando spring framework 2.0, isto funciona perfeitamente …
Caso contrario, só é possivel injetar um entity manager factory em um Session Bean ou então em um Servlet …

[quote=ynaue]Vc diz fazer isso???

[code]public class EstruturaDAO {

 @PersistenceContext
private EntityManager em;

public EstruturaDAO() {
}

public Estrutura localiza(int id ) throws PersistenceException {
    
    try{
        Estrutura p= em.find(Estrutura.class,id);
        return p;
    } catch(PersistenceException pe) {
        pe.printStackTrace();
        return null;
    } catch(Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        em.close();
    }
    
}[/code]

Mas e o EntityManagerFactory ???

Obrigada![/quote]

[color=red][size=18]Ai SOOOCCCOOORRROOOOO !!![/size][/color]

O Projeto não esta usando Spring.

Na verdade me pediram para cuidar apenas dessa parte de acesso ao BD.
Então fiz o mapeamento das tabelas (classes com gets e sets), o perisitence.xml, e as classes que chamei de DAO onde adiciono, atualizo e removo os dados.

Como mostrado na minha primeira mensagem estava fazendo a conexão daquele jeito (que deve estar errado)

E realmente essa ultima ideia não deu certo.
E agora???

Ahh!! Estou usando o TopLink

E, se não me engano, você não precisa chamar o método close() num ambiente gerenciado (dentro do container JEE).

Voce esta abrindo muitas EMFs!!! Tudo bem que esta fechando direito o EM, mas o EMF voce esta abrindo demais, ele pode estar criando um pool para cada EMF, nao sei como o toplink gerencia isso!

Faca o seguinte, devolve sempre a mesma EMF pelo seu JPAConexao, a la singleton. Mais para frente mude isso para injecao de dependencias.

[quote=Paulo Silveira]Voce esta abrindo muitas EMFs!!! Tudo bem que esta fechando direito o EM, mas o EMF voce esta abrindo demais, ele pode estar criando um pool para cada EMF, nao sei como o toplink gerencia isso!

Faca o seguinte, devolve sempre a mesma EMF pelo seu JPAConexao, a la singleton. Mais para frente mude isso para injecao de dependencias.[/quote]

Mas ja não é isso que estou fazendo aqui (singleton)???

[code]public class JPAConexao {

 protected static EntityManagerFactory emf;

  public static EntityManagerFactory getFactory (){
     if (emf == null)
     {
         emf = Persistence.createEntityManagerFactory("BancoPU");  
     }
     return emf;
 }

}[/code]

verdade, ja esta fazendo!

mande a stacktrace… e verifique o erro que o PG ta reclamando!

[size=18]HELP!!![/size]

Demorou para apareceu de novo!!! O erro é esse:

E esse é o que parece no Log no netbeans:

[quote]Local Exception Stack:
Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2006.4 (Build 060412)): oracle.toplink.essentials.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: FATAL: sorry, too many clients alreadyError Code: 0
at oracle.toplink.essentials.exceptions.DatabaseException.sqlException(DatabaseException.java:289)
at oracle.toplink.essentials.sessions.DefaultConnector.connect(DefaultConnector.java:84)
at oracle.toplink.essentials.sessions.DatasourceLogin.connectToDatasource(DatasourceLogin.java:167)
at oracle.toplink.essentials.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:537)
at oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:193)
at oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider.createEntityManagerFactory(EntityManagerFactoryProvider.java:129)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:83)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:60)
at pacotes.persistencias.connector.JPAConexao.getFactory(JPAConexao.java:30)
at pacotes.persistencias.DAO.MenuDAO.atualizar(MenuDAO.java:105)
at org.apache.jsp.index_005fMenu_jsp._jspService(index_005fMenu_jsp.java:106)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:332)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:368)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Thread.java:595)
Caused by: org.postgresql.util.PSQLException: FATAL: sorry, too many clients already
at org.postgresql.core.v3.ConnectionFactoryImpl.readStartupMessages(ConnectionFactoryImpl.java:443)
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:98)
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:66)
at org.postgresql.jdbc2.AbstractJdbc2Connection.(AbstractJdbc2Connection.java:125)
at org.postgresql.jdbc3.AbstractJdbc3Connection.(AbstractJdbc3Connection.java:30)
at org.postgresql.jdbc3.Jdbc3Connection.(Jdbc3Connection.java:24)
at org.postgresql.Driver.makeConnection(Driver.java:382)
at org.postgresql.Driver.connect(Driver.java:260)
at java.sql.DriverManager.getConnection(DriverManager.java:525)
at java.sql.DriverManager.getConnection(DriverManager.java:140)
at oracle.toplink.essentials.sessions.DefaultConnector.connect(DefaultConnector.java:82)
… 32 more[/quote]

Estou com um problema parecido…vc conseguiu resolver???
Se conseguiu, pode me mostrar a solução?
Obrigado…

Ainda não consegui não…

Vc tb esta usando Postgres???

E qdo vc insere dados em uma tabela com relacionamento e Sequence esse dado consegue ser listado logo em seguida???
Pq estou com esse problema tb.

[quote=ynaue]Vc diz fazer isso???

[code]public class EstruturaDAO {

 @PersistenceContext
private EntityManager em;

public EstruturaDAO() {
}

public Estrutura localiza(int id ) throws PersistenceException {
    
    try{
        Estrutura p= em.find(Estrutura.class,id);
        return p;
    } catch(PersistenceException pe) {
        pe.printStackTrace();
        return null;
    } catch(Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        em.close();
    }
    
}[/code]

Mas e o EntityManagerFactory ???

Obrigada![/quote]

vc tem certeza que existe apenas um registro com esse id no banco? ele deve estar retornando uma lista.

Estou com o mesmo erro que vc ynaue. Estou agora utilizando TopLink em vez do Hibernate, e estou usando banco postgres 8.2 . O Erro é identico ao seu, se conseguir resolver me passa por favor.