Hibernate. erro ao obter lista

26 respostas
R

Estou recebendo esse log de erro quando eu tento executar o seguinte:

Session sessao = GerenciadorHibernate.getSession(); List<Cliente>clientes = sessao.createCriteria(Cliente.class).list(); sessao.close(); return clientes;

Quando eu executo pela segunda vez, o resultado é obtido.
Se eu executo pelo debug, o resultado é obtido da primeira vez, e o erro continua a ser exibido.

No meio desse log tem:
Caused by: org.firebirdsql.jdbc.FBSQLException: This statement is already closed.
Alguém sabe o que significa isso?

Initializing c3p0 pool com.mchange.v2.c3p0.PoolBackedDataSource@12f0999 [ connectionPoolDataSource -> com.mchange.v2.c3p0.WrapperConnectionPoolDataSource@2d9c06 [ acquireIncrement -> 1, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, idleConnectionTestPeriod -> 3000, initialPoolSize -> 5, maxIdleTime -> 300, maxPoolSize -> 20, maxStatements -> 50, maxStatementsPerConnection -> 0, minPoolSize -> 5, nestedDataSource -> com.mchange.v2.c3p0.DriverManagerDataSource@1808199 [ description -> null, driverClass -> null, factoryClassLocation -> null, jdbcUrl -> jdbc:firebirdsql://servidor:3050/c:\SOR\BANCO.FDB, properties -> {user=******, password=******} ] , preferredTestQuery -> null, propertyCycle -> 300, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, usesTraditionalReflectiveProxies -> false ] , factoryClassLocation -> null, numHelperThreads -> 3, poolOwnerIdentityToken -> 12f0999 ]

00:35:20,49700:35:24,49200:35:24,492Exception in thread AWT-EventQueue-0 org.hibernate.exception.GenericJDBCException: could not execute query

at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:82)

at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:70)

at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)

at org.hibernate.loader.Loader.doList(Loader.java:1518)

at org.hibernate.loader.Loader.list(Loader.java:1498)

at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:111)

at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1253)

at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:299)

at src.model.GerenciadorCliente.getClientes(GerenciadorCliente.java:31)

at src.controller.ControladorTelaPesquisaCliente$6.actionPerformed(ControladorTelaPesquisaCliente.java:56)

at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1849)

at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2169)

at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:420)

at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:258)

at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:234)

at java.awt.Component.processMouseEvent(Component.java:5488)

at javax.swing.JComponent.processMouseEvent(JComponent.java:3093)

at java.awt.Component.processEvent(Component.java:5253)

at java.awt.Container.processEvent(Container.java:1966)

at java.awt.Component.dispatchEventImpl(Component.java:3955)

at java.awt.Container.dispatchEventImpl(Container.java:2024)

at java.awt.Component.dispatchEvent(Component.java:3803)

at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4212)

at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3892)

at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3822)

at java.awt.Container.dispatchEventImpl(Container.java:2010)

at java.awt.Window.dispatchEventImpl(Window.java:1766)

at java.awt.Component.dispatchEvent(Component.java:3803)

at java.awt.EventQueue.dispatchEvent(EventQueue.java:463)

at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:234)

at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)

at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)

at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)

at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)

Caused by: org.firebirdsql.jdbc.FBSQLException: This statement is already closed.

at org.firebirdsql.jdbc.AbstractStatement.close(AbstractStatement.java:225)

at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.close(NewProxyPreparedStatement.java:1674)

at org.hibernate.jdbc.AbstractBatcher.closePreparedStatement(AbstractBatcher.java:393)

at org.hibernate.jdbc.AbstractBatcher.closeStatement(AbstractBatcher.java:195)

at org.hibernate.jdbc.AbstractBatcher.closeQueryStatement(AbstractBatcher.java:212)

at org.hibernate.jdbc.AbstractBatcher.closeQueryStatement(AbstractBatcher.java:141)

at org.hibernate.loader.Loader.doQuery(Loader.java:408)

at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:206)

at org.hibernate.loader.Loader.doList(Loader.java:1515)

 30 more

26 Respostas

F

Para mais detalhes vc poderia postar o contexto em que esse cara é chamado, mas, a principio, confira se sua conexão com o banco não está fechada.

flw

R

O que a respeito do contexto? É chamado quando o usuário pressiona um botão na gui.
Antes disso só tem a criação do sessionfactory.
O problema não é na apresentação do conteúdo, pois se eu criar a lista de objetos manualmente, eles são apresentados corretamente.

Veja no código abaixo. Se eu deixo o código retornar os objetos criados para teste, não tenho problemas. Se eu executo o getTodosClientes, o problema ocorre.

public static List<Cliente> getClientes(String nome){ List<Cliente> clientes = new ArrayList<Cliente>(); if (nome != null && nome.equals("Jose")){ Cliente cliente1 = new Cliente("Jose Mariano"); cliente1.setId(1); Cliente cliente2 = new Cliente("Jose Gomes"); cliente2.setId(2); Cliente cliente3 = new Cliente("Jose Pereira"); cliente3.setId(3); clientes.add(cliente1); clientes.add(cliente2); clientes.add(cliente3); } //return clientes; return getTodosClientes(); } public static List<Cliente> getTodosClientes(){ Session sessao = GerenciadorHibernate.getSession(); List<Cliente>clientes = sessao.createCriteria(Cliente.class).list(); sessao.close(); return clientes; }

_fs

Depois de carregar os clientes você tenta acessar alguma collection de cada um deles? Por exemplo:

( ( Cliente ) list.get( 0 ) ).getDocumentos();
R

Nâo, não tento.
Depois de carregas os clientes eu passo eles para o objeto tableModel, com um setLinhas e depois eu uso conversão para acessar alguns atributos.
Está um pouco estranho. Hoje, tentei fazer o teste. Na primeira vez os resultados apareceram, mas deu erro na console. Na segunda vez, só erro.

R

No código abaixo, quando é executado a linha Listclientes = sessao.createCriteria(Cliente.class).list();, o erro abaixo é gerado.

public static List<Cliente> getTodosClientes(){ Session sessao = GerenciadorHibernate.getSession(); List<Cliente>clientes = sessao.createCriteria(Cliente.class).list(); sessao.close(); return clientes; }

org.firebirdsql.jdbc.FBSQLException: This statement is already closed.

at org.firebirdsql.jdbc.AbstractStatement.close(AbstractStatement.java:225)

at com.mchange.v1.db.sql.StatementUtils.attemptClose(StatementUtils.java:38)

at com.mchange.v2.c3p0.stmt.GooGooStatementCache$1.run(GooGooStatementCache.java:246)

at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:354)
_fs

Então consigo pensar em duas possiblidades:
a. isso aqui

GerenciadorHibernate.getSession();

não está fazendo o trabalho direito. Você consegue utilizar o objeto Session retornado por este método em outras consultas que não essa que está dando erro?
b. alguma outra thread está fechando a conexão.

R

Oi, essa é a primeira coisa que estou fazendo no programa. É meu primeiro teste com o hibernate. Todas as vezes que eu debugo a aplicação, eu inspeciono a variável clientes e ela está com o conteúdo certo. Mas, as vezes, em tempo de execução, o resultado não é apresentado na tela.
Mas em qualquer situação, mesmo quando estou debugando, e erro que eu falei na mensagem anterior é apresentado.

Minha classe GerenciadorHiberante é bem simples.
public class GerenciadorHibernate {

	private static SessionFactory fabricaDeSessoes;
	
	public static void iniciar() {
		fabricaDeSessoes = new Configuration().configure().buildSessionFactory();
	}
	
	public static Session getSession(){
		return fabricaDeSessoes.openSession();
	}

}
Veja o meu main:
public static void main(String[] args) {
	//criar fabrica de sessoes do hibernate
	GerenciadorHibernate.iniciar();        
	//Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
R

Não sei se ajuda, mas segue abaixo o arquivo hibernate.properties e hibernate.cfg.xml

hibernate.connection.driver_class = org.firebirdsql.jdbc.FBDriver hibernate.connection.url = jdbc:firebirdsql://servidor:3050/c:\\SOR\\BANCO.FDB hibernate.connection.username = SYSDBA hibernate.connection.password = masterkey hibernate.dialect = org.hibernate.dialect.FirebirdDialect hibernate.c3p0.min_size=5 hibernate.c3p0.max_size=20 hibernate.c3p0.timeout=300 hibernate.c3p0.max_statements=50 hibernate.c3p0.idle_test_period=3000
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

    <session-factory>

        <!-- arquivos de mapeamentos -->
        <mapping resource="src/model/hibernate/Cliente.hbm.xml"/>
        <mapping resource="src/model/hibernate/Orcamento.hbm.xml"/>
        
    </session-factory>

</hibernate-configuration>
_fs

Erros de mapeamento e de conexão possuem exceções próprias.

Cara, tenta fazer um simples

Cliente c = ( Cliente ) session.get( Cliente.class, id ); // id é a chave primaria da tabela
R
 esse erro:

14:07:29,871Hibernate: select cliente0_.CLIENTE_ID as CLIENTE1_0_, cliente0_.nome as nome0_0_ from CLIENTE cliente0_ where cliente0_.CLIENTE_ID=?

org.firebirdsql.jdbc.FBSQLException: This statement is already closed.

at org.firebirdsql.jdbc.AbstractStatement.close(AbstractStatement.java:225)

at com.mchange.v1.db.sql.StatementUtils.attemptClose(StatementUtils.java:38)

at com.mchange.v2.c3p0.stmt.GooGooStatementCache$1.run(GooGooStatementCache.java:246)

at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:354)

Mesmo dando o erro, as vezes o resultado é apresentado, outras vezes não. Se eu clico no botão e deixo o mouse onde está, o resultado não é mostrado. Se clico e tiro o mouse de cima do botão, o resultado não é mostrado. De qualquer forma, o erro sempre é mostrado.

R

Se alguém quiser tentar rodar, segue em anexo o projeto do eclipse.

R

Tentei salvar um objeto. Da erro e não é salvado no banco de dados. Mas o generator é incrementado.

Cliente cliente2 = new Cliente("Renato Pena Leve"); sessao.save(cliente2);
14:43:13,284Hibernate: select gen_id( CLIENTE_GEN, 1 ) from RDB$DATABASE
org.firebirdsql.jdbc.FBSQLException: This statement is already closed.
at org.firebirdsql.jdbc.AbstractStatement.close(AbstractStatement.java:225)
at com.mchange.v1.db.sql.StatementUtils.attemptClose(StatementUtils.java:38)
at com.mchange.v2.c3p0.stmt.GooGooStatementCache$1.run(GooGooStatementCache.java:246)
at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:354)

_fs

Cara, você tá usando algum pool? Está usando a última versão do driver?

R

Eu não sei direito como funciona pool. Conorme mostrei acima, coloquei essas linhas no hibernate.properties.

hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=20
hibernate.c3p0.timeout=300
hibernate.c3p0.max_statements=50
hibernate.c3p0.idle_test_period=3000

A biblioteca c3p0-0.8.5.jar que estava no diretório lib do hibernate está no meu classpath.

_fs

O erro ocorre exatamente na linha

session.save( Cliente );

?

R

Isso, eu debuguei a aplicação e dá esse erro na linha sessao.save(cliente);

16:16:19,055Hibernate: select gen_id( CLIENTE_GEN, 1 ) from RDB$DATABASE

org.firebirdsql.jdbc.FBSQLException: This statement is already closed.

at org.firebirdsql.jdbc.AbstractStatement.close(AbstractStatement.java:225)

at com.mchange.v1.db.sql.StatementUtils.attemptClose(StatementUtils.java:38)

at com.mchange.v2.c3p0.stmt.GooGooStatementCache$1.run(GooGooStatementCache.java:246)

at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:354)
_fs

Bom, então o Hibernate foi capaz de fazer o INSERT, mas na hora do SELECT para pegar o ID gerado deu erro.

Tenta fazer um select normal ( session.get() ), num Objeto sem relacionamentos, assim você estará testando se algum erro ocorre ao enviar apenas uma instrução para database.

R

Também da erro. Veja abaixo a saída quando eu executo normalmente. Se eu executar pelo debug, da um erro menor.

Erro sem o debug

17:20:59,035Hibernate: select cliente0_.CLIENTE_ID as CLIENTE1_0_, cliente0_.nome as nome0_0_ from CLIENTE cliente0_ where cliente0_.CLIENTE_ID=?

17:21:05,12317:21:05,123Exception in thread AWT-EventQueue-0 org.hibernate.exception.GenericJDBCException: could not load an entity: [src.model.Cliente#1]

at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:82)

at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:70)

at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)

at org.hibernate.loader.Loader.loadEntity(Loader.java:1285)

at org.hibernate.loader.entity.EntityLoader.load(EntityLoader.java:141)

at org.hibernate.loader.entity.EntityLoader.load(EntityLoader.java:126)

at org.hibernate.persister.entity.BasicEntityPersister.load(BasicEntityPersister.java:2496)

at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:387)

at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:368)

at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:166)

at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:140)

at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:249)

at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:123)

at org.hibernate.impl.SessionImpl.get(SessionImpl.java:561)

at org.hibernate.impl.SessionImpl.get(SessionImpl.java:556)

at src.model.GerenciadorCliente.getClientes(GerenciadorCliente.java:27)

at src.controller.ControladorTelaPesquisaCliente$6.actionPerformed(ControladorTelaPesquisaCliente.java:61)

at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1849)

at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2169)

at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:420)

at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:258)

at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:234)

at java.awt.Component.processMouseEvent(Component.java:5488)

at javax.swing.JComponent.processMouseEvent(JComponent.java:3093)

at java.awt.Component.processEvent(Component.java:5253)

at java.awt.Container.processEvent(Container.java:1966)

at java.awt.Component.dispatchEventImpl(Component.java:3955)

at java.awt.Container.dispatchEventImpl(Container.java:2024)

at java.awt.Component.dispatchEvent(Component.java:3803)

at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4212)

at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3892)

at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3822)

at java.awt.Container.dispatchEventImpl(Container.java:2010)

at java.awt.Window.dispatchEventImpl(Window.java:1766)

at java.awt.Component.dispatchEvent(Component.java:3803)

at java.awt.EventQueue.dispatchEvent(EventQueue.java:463)

at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:234)

at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)

at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)

at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)

at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)

Caused by: org.firebirdsql.jdbc.FBSQLException: This statement is already closed.

at org.firebirdsql.jdbc.AbstractStatement.close(AbstractStatement.java:225)

at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.close(NewProxyPreparedStatement.java:1674)

at org.hibernate.jdbc.AbstractBatcher.closePreparedStatement(AbstractBatcher.java:393)

at org.hibernate.jdbc.AbstractBatcher.closeStatement(AbstractBatcher.java:195)

at org.hibernate.jdbc.AbstractBatcher.closeQueryStatement(AbstractBatcher.java:212)

at org.hibernate.jdbc.AbstractBatcher.closeQueryStatement(AbstractBatcher.java:141)

at org.hibernate.loader.Loader.doQuery(Loader.java:408)

at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:206)

at org.hibernate.loader.Loader.loadEntity(Loader.java:1271)

 37 more

Erro quando eu debugo

17:22:39,088Hibernate: select cliente0_.CLIENTE_ID as CLIENTE1_0_, cliente0_.nome as nome0_0_ from CLIENTE cliente0_ where cliente0_.CLIENTE_ID=?

org.firebirdsql.jdbc.FBSQLException: This statement is already closed.

at org.firebirdsql.jdbc.AbstractStatement.close(AbstractStatement.java:225)

at com.mchange.v1.db.sql.StatementUtils.attemptClose(StatementUtils.java:38)

at com.mchange.v2.c3p0.stmt.GooGooStatementCache$1.run(GooGooStatementCache.java:246)

at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:354)
R

Veja meu arquivo de mapeamento e o de propriedades. Talvez existe algo errado neles.

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

    <session-factory>

        <!-- arquivos de mapeamentos -->
        <mapping resource="src/model/hibernate/Cliente.hbm.xml"/>

        
    </session-factory>

</hibernate-configuration>

Arquivo de propriedades:

hibernate.connection.driver_class = org.firebirdsql.jdbc.FBDriver
hibernate.connection.url = jdbc:firebirdsql://servidor:3050/c:\\SOR\\BANCO.FDB
hibernate.connection.username = SYSDBA
hibernate.connection.password = masterkey
hibernate.show_sql = true
hibernate.dialect = org.hibernate.dialect.FirebirdDialect
hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=20
hibernate.c3p0.timeout=300
hibernate.c3p0.max_statements=50
hibernate.c3p0.idle_test_period=3000

_fs

Bizarro :smiley:

Procurei no fórum do Hibernate e dos tres tópicos que encontrei 2 tinham replies sugerindo erros com o pool. Então tenta tirar configurações do c3p0.

louds

Todos erros falam que os statements estão fechados. Seu problema é relacionado ao gerenciamento de conexão.

R

Funcionou sem erros quando eu tirei as configurações do pool.
Tirei as seguintes linhas do arquivo hibernate.properties.

hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=20
hibernate.c3p0.timeout=300
hibernate.c3p0.max_statements=50
hibernate.c3p0.idle_test_period=3000

Eu nunca tentei fazer esse teste pois em algumas documentações que li diziam que era recomendado usar algum framework para pool.

Em primeiro lugar, muito obrigado ao LIPE e ao louds, que responderam o tópico. Agora que sei o motivo dos erros, preciso saber como proceder.

Eu poderia trabalhar sem o c3p0? Ou seria recomendável eu resolver esse problema e usar o c3p0? Como vocês costumam trabalhar? Tem alguma configuração que eu deveria fazer para o c3p0 trabalhar corretamente?

O que seria o gerenciamento de conexao mencionado pelo louds? No meu código eu não tenho nenhum tipo de gerência de conexao que eu fiz. Eu apenas coloquei aquelas linhas no arquivo hibernate.properties. Eu deveria ter feito algum outro tipo de configuração gerenciamento de conexao?

Fiz o teste de salvar o objeto e salvou no banco de dados, apesar do erro. No primeiro teste, não salvou pois eu não estava abrindo uma transação e dando o commit.

_fs

O c3p0 faz o gerenciamento da conexão, por isso o erro, como o louds falou.

Eu uso o c3p0 sem problemas, com quase as mesmas configurações com você. Certifique-se que baixou o jar da última versão do driver.

Há um outro pool, o dpbc, mas é muito mal falado.

E é sim imprescindivel usar algum pool, pois o que vem “built-in” no Hibernate, como eles mesmos dizem, não deve ser usado em ambiente de produção.

E mais um último detalhe: não precisa abrir uma transação se não é necessário. Pode apenas fazer session.flush(). Assim todas as modificações são enviadas para o banco de dados.

R

Estou usando o c3p0-0.8.5.jar e hibernate3.jar.
É esse que vocês estão usando?

R

Pessoal,
coloquei o c3p0-0.8.5.1.jar e o problema não ocorreu mais.

_fs

Eba :smiley:

Criado 20 de abril de 2005
Ultima resposta 26 de abr. de 2005
Respostas 26
Participantes 4