Tenho um objeto que é composto de vários outros.
PecaEstrutural<>------> * ItensDePecaEstrutural
Quando salvo o objeto, ele salva corretamente se a coleção itens tiver apenas 1 objeto. Se tiver 2, dá o erro abaixo.
Quando eu faço o commit, ele faz o insert do log abaixo e o restante.
O que tem antes do insert, é gerado antes do commit.
Hibernate: select this_.PECA_ESTRUTURAL_ID as PECA1_0_, this_.VERSAO as VERSAO3_0_, this_.descricao as descricao3_0_,
this_.QTD_CHARUTOS as QTD5_3_0_, this_.TIPO as TIPO0_ from PECA_ESTRUTURAL this_
Hibernate: select gen_id( PECA_ESTRUTURAL_GEN, 1 ) from RDB$DATABASE
Hibernate: select this_.DESCRICAO_MATERIAL_ID as DESCRICAO1_0_, this_.VERSAO as VERSAO2_0_, this_.nome as nome2_0_,
this_.UNIDADE_MEDIDA as UNIDADE4_2_0_ from DESCRICAO_MATERIAL this_
Hibernate: select this_.DESCRICAO_MATERIAL_ID as DESCRICAO1_0_, this_.VERSAO as VERSAO2_0_, this_.nome as nome2_0_,
this_.UNIDADE_MEDIDA as UNIDADE4_2_0_ from DESCRICAO_MATERIAL this_
Hibernate: insert into PECA_ESTRUTURAL (VERSAO, descricao, QTD_CHARUTOS, TIPO, PECA_ESTRUTURAL_ID) values (?, ?, ?,
'Portico', ?)
Hibernate: select gen_id(
ITEM_PECA_ESTRUTURAL_GEN
, 1 ) from RDB$DATABASE
Hibernate: select gen_id(
ITEM_PECA_ESTRUTURAL_GEN
, 1 ) from RDB$DATABASE
Problem with checked-in Statement, discarding.
java.lang.NullPointerException
at org.firebirdsql.jdbc.AbstractPreparedStatement.clearParameters(AbstractPreparedStatement.java:349)
at com.mchange.v2.c3p0.stmt.GooGooStatementCache.refreshStatement(GooGooStatementCache.java:410)
at com.mchange.v2.c3p0.stmt.GooGooStatementCache.checkinStatement(GooGooStatementCache.java:129)
at com.mchange.v2.c3p0.impl.NewPooledConnection.checkinStatement(NewPooledConnection.java:143)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.close(NewProxyPreparedStatement.java:1670)
at org.hibernate.jdbc.AbstractBatcher.closePreparedStatement(AbstractBatcher.java:393)
at org.hibernate.jdbc.AbstractBatcher.closeStatement(AbstractBatcher.java:195)
at org.hibernate.id.SequenceGenerator.generate(SequenceGenerator.java:91)
at org.hibernate.collection.PersistentIdentifierBag.preInsert(PersistentIdentifierBag.java:294)
at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:851)
at org.hibernate.action.CollectionRecreateAction.execute(CollectionRecreateAction.java:23)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:239)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:223)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:274)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:675)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:293)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:86)
at src.controller.ControladorTelaEdicaoPecaEstrutural.<init>(ControladorTelaEdicaoPecaEstrutural.java:30)
at src.controller.ControladorTelaPesquisaPecaEstrutural.acaoInserir(ControladorTelaPesquisaPecaEstrutural.java:38)
at src.controller.ControladorTelaPesquisaModelo$4.actionPerformed(ControladorTelaPesquisaModelo.java:70)
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)20:07:53,55020:07:53,550
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)
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)
20:07:53,560org.hibernate.exception.GenericJDBCException: could not get next sequence value
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.id.SequenceGenerator.generate(SequenceGenerator.java:96)
at org.hibernate.collection.PersistentIdentifierBag.preInsert(PersistentIdentifierBag.java:294)
at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:851)
at org.hibernate.action.CollectionRecreateAction.execute(CollectionRecreateAction.java:23)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:239)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:223)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:274)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:675)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:293)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:86)
at src.controller.ControladorTelaEdicaoPecaEstrutural.<init>(ControladorTelaEdicaoPecaEstrutural.java:30)
at src.controller.ControladorTelaPesquisaPecaEstrutural.acaoInserir(ControladorTelaPesquisaPecaEstrutural.java:38)
at src.controller.ControladorTelaPesquisaModelo$4.actionPerformed(ControladorTelaPesquisaModelo.java:70)
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.id.SequenceGenerator.generate(SequenceGenerator.java:91)
... 38 more
Pois é, mas quando é um erro do próprio Hibernate ele dá uma mensagem dele ou mostra a mensagem do banco, nesse caso o erro está ocorrendo porque o banco parece ter fechado o result set antes do Hibernate terminar de carregar todos os objetos, o que não deveria estar acontecendo.
Eu acho difícil disso ser erro no hibernate, você poderia mostrar os mapeamentos e as classes que estão sendo persistidas?
Fiz uma classe de teste para a situação. Veja abaixo:
[code] public static void main(String[] args) {
Session session = HibernateUtil.getSession();
Transaction trans = session.beginTransaction();
PecaEstrutural pecaEstrutural = new Portico();
pecaEstrutural.setDescricao(“Portico teste 50metros de vão”);
pecaEstrutural.setQuantidadeCharutos(4);
session.saveOrUpdate(pecaEstrutural);
List lista = pecaEstrutural.getItens();
// session.lock(pecaEstrutural,LockMode.NONE);
ItemPecaEstrutural item1 = new ItemPecaEstrutural();
item1.setQuantidade(44);
item1.setTotal(new BigDecimal("334.43"));
Session sessao1 = HibernateUtil.getSession();
DescricaoMaterial descricaoMaterial1 = new DescricaoMaterial();
sessao1.load(descricaoMaterial1,new Integer(1));
sessao1.close();
item1.setDescricaoMaterial(descricaoMaterial1);
pecaEstrutural.addItem(item1);
ItemPecaEstrutural item2 = new ItemPecaEstrutural();
item2.setQuantidade(34);
item2.setTotal(new BigDecimal("4.43"));
Session sessao2 = HibernateUtil.getSession();
DescricaoMaterial descricaoMaterial2 = new DescricaoMaterial();
sessao2.load(descricaoMaterial2,new Integer(2));
sessao2.close();
item2.setDescricaoMaterial(descricaoMaterial2);
pecaEstrutural.addItem(item2);
Integer pk = pecaEstrutural.getId();
trans.commit();
session.close();
Session sessao3 = HibernateUtil.getSession();
PecaEstrutural pe = new Portico();
sessao3.load(pe,pk);
assert pk == pe.getId(): "Não foi gravado.";
}[/code]
Olha, não sei como você está fazendo pra pegar essas sessões, nem sei porque você está abrindo e fechando uma dúzia de sessões ao mesmo tempo quando apenas uma seria mais do que o suficiente, mas tente usar a mesma sessão que você abriu no início do código pra fazer tudo, se der erro você posta aqui.
Outra coisa, você está usando ThreadLocal? Como é que funciona a classe que abre as sessões?
Oi não estou usando thread local não. Minha aplicação é uma aplicação desktop c/ swing sem servidor de aplicação. Acesso apenas o banco de dados. Veja minha classe Hibernateutil abaixo. Eu abro várias sessoes, pois quero simular o que está acontecendo no programa. No programa, tem os métodos de obter objetos, que possuem suas próprias sessoes.
Além disso, tenho a tela de pesquisa e a tela de edição. Cada uma dessas tem sua própria sessao.
Só que nessa classe HibernateUtil você está abrindo e fechando as sessões junto com as transações, o comportamento normal do Hibernate, diferentemente do seu código de testes, onde você abre sessões sem transações e mistura diversos objetos em sessões diferentes com objetos que não estão mais em sessão nenhuma.
Veja que na sua classe HibernateUtil, o objeto só é retornado quando o Hibernate faz o commit na transação e fecha a sessão, o que quer dizer que todos os objetos que saem dali estão “soltos”, não fazem mais parte de sessão nenhuma.
Faça um teste usando essa sua classe HibernateUtil.
Iniciar transações é sempre obrigatório? Realmente, no meu código não inicio transações sempre. Na minha classe hibernateUtils, faço isso nos métodos padrões.
Acho que tem um erro no meu mapeamento. Minha classe ItemPecaEstrutural compõe a classe PecaEstrutural. No mapeamento, eu indico que o id da coleção é o campo ITEM_PECA_ESTRUTURAL_ID da tabela. Mas eu não tenho uma propriedade para essa coluna.
Acho que esse pode ser o erro. Alguém sabe como eu poderia incluir isso nesse mapeamento?
Fiz a modificação para usar apenas 1 seção e 1 transação. Mas deu o erro abaixo, ao fazer o segundo load.
[code]public class testeGerenciarPecaEstrutural {
public static void main(String[] args) {
Session sessao = HibernateUtil.getSession();
Transaction trans = sessao.beginTransaction();
//cria objeto composto
PecaEstrutural pecaEstrutural = new Portico();
pecaEstrutural.setDescricao("Portico teste 50metros de vão");
pecaEstrutural.setQuantidadeCharutos(4);
sessao.saveOrUpdate(pecaEstrutural);
List lista = pecaEstrutural.getItens();
// session.lock(pecaEstrutural,LockMode.NONE);
//cria primeira composição
ItemPecaEstrutural item1 = new ItemPecaEstrutural();
item1.setQuantidade(44);
item1.setTotal(new BigDecimal("334.43"));
// Session sessao1 = HibernateUtil.getSession();
// Transaction trans1 = sessao1.beginTransaction();
DescricaoMaterial descricaoMaterial1 = new DescricaoMaterial();
sessao.load(descricaoMaterial1,new Integer(1));
// trans1.commit();
// sessao1.close();
item1.setDescricaoMaterial(descricaoMaterial1);
pecaEstrutural.addItem(item1);
//cria segunda composição
ItemPecaEstrutural item2 = new ItemPecaEstrutural();
item2.setQuantidade(34);
item2.setTotal(new BigDecimal("4.43"));
// Session sessao2 = HibernateUtil.getSession();
// Transaction trans2 = sessao2.beginTransaction();
DescricaoMaterial descricaoMaterial2 = new DescricaoMaterial();
// dá erro ao fazer esse load
sessao.load(descricaoMaterial2,new Integer(2));
// trans2.commit();
// sessao2.close();
item2.setDescricaoMaterial(descricaoMaterial2);
pecaEstrutural.addItem(item2);
Integer pk = pecaEstrutural.getId();
trans.commit();
sessao.close();
Session sessao3 = HibernateUtil.getSession();
PecaEstrutural pe = new Portico();
sessao3.load(pe,pk);
assert pk == pe.getId(): "Não foi gravado.";
}
}
Hibernate: select descricaom0_.DESCRICAO_MATERIAL_ID as DESCRICAO1_0_, descricaom0_.VERSAO as VERSAO2_0_, descricaom0_.nome as nome2_0_, descricaom0_.UNIDADE_MEDIDA as UNIDADE4_2_0_ from DESCRICAO_MATERIAL descricaom0_ where descricaom0_.DESCRICAO_MATERIAL_ID=?
Problem with checked-in Statement, discarding.
java.lang.NullPointerException
at org.firebirdsql.jdbc.AbstractPreparedStatement.clearParameters(AbstractPreparedStatement.java:349)
at com.mchange.v2.c3p0.stmt.GooGooStatementCache.refreshStatement(GooGooStatementCache.java:410)
at com.mchange.v2.c3p0.stmt.GooGooStatementCache.checkinStatement(GooGooStatementCache.java:129)
at com.mchange.v2.c3p0.impl.NewPooledConnection.checkinStatement(NewPooledConnection.java:143)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.close(NewProxyPreparedStatement.java:1670)
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.getResultSet(Loader.java:1207)
at org.hibernate.loader.Loader.doQuery(Loader.java:366)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:206)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1271)
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.load(SessionImpl.java:540)
at src.testeGerenciarPecaEstrutural.main(testeGerenciarPecaEstrutural.java:45)
10:55:15,70110:55:15,701Exception in thread “main” org.hibernate.exception.GenericJDBCException: could not load an entity: [src.model.DescricaoMaterial#2]
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.load(SessionImpl.java:540)
at src.testeGerenciarPecaEstrutural.main(testeGerenciarPecaEstrutural.java:45)
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.getResultSet(Loader.java:1207)
at org.hibernate.loader.Loader.doQuery(Loader.java:366)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:206)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1271)
… 11 more
O erro continua sendo porque os statements parecem estar fechados, faça como eu disse lá no início e use uma única sessão e uma única transação pra tudo, só pra ver no que vai dar.
Não sei se você reparou.
Quando eu coloco tudo em uma mesma sesso, o problema muda. Ai começa a dar erro ao fazer o segundo Load. Ele faz a consulta sql e dá o erro.
Vai saber como que o pool está falando com o driver que está falando com o banco.
Leia novamente, desta vez com mais cuidado, a documentação do pool e do driver, com certeza há algum detalhe.