Hibernate. erro ao salvar objeto com + de 2 itens [resolvido]

21 respostas
R

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

21 Respostas

Mauricio_Linhares

O erro não parece ser do Hibernate companheiro, tá vindo lá do seu driver JDBC.

R

Mas o erro é gerado quando eu faço um commit na transação do hibernate.

Mauricio_Linhares

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?

R
Fiz uma classe de teste para a situação. Veja abaixo:
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.";
	}
<hibernate-mapping>

	<class name="src.model.PecaEstrutural" table="PECA_ESTRUTURAL">

		<id name="id" column="PECA_ESTRUTURAL_ID">
			<generator class="sequence">
				<param name="sequence">PECA_ESTRUTURAL_GEN</param>
			</generator>
		</id>

		<discriminator column="TIPO"/>

		<version name="versao" column="VERSAO" />

		<property name="descricao" unique="true" not-null="true" />

		<property name="quantidadeCharutos" column="QTD_CHARUTOS" not-null="true" />

		<idbag name="itens" lazy="true" cascade="all-delete-orphan"
			table="ITEM_PECA_ESTRUTURAL">
			<collection-id type="integer"
				column="ITEM_PECA_ESTRUTURAL_ID">
				<generator class="sequence">
					<param name="sequence">
						ITEM_PECA_ESTRUTURAL_GEN
					</param>
				</generator>
			</collection-id>
			<key column="PECA_ESTRUTURAL_ID" not-null="true" />
			<composite-element class="src.model.ItemPecaEstrutural">
				<property name="quantidade" />
				<property name="total" />
				<many-to-one name="descricaoMaterial" column="DESCRICAO_MATERIAL_ID" />
			</composite-element>
		</idbag>
		
		<subclass
			name="src.model.Tesoura"
			discriminator-value="Tesoura">
		</subclass>			
		
		<subclass
			name="src.model.Portico"
			discriminator-value="Portico">
		</subclass>					

	</class>

</hibernate-mapping>


<hibernate-mapping>

        <class name="src.model.DescricaoMaterial" table="DESCRICAO_MATERIAL">
                
                <id name="id" column="DESCRICAO_MATERIAL_ID">
                        <generator class="sequence">
                        	<param name="sequence">DESCRICAO_MATERIAL_GEN</param>
                        </generator>
                </id>
                
                <version name="versao" column="VERSAO"/>

                <property name="nome" unique="true" not-null="true"/>

				<property name="unidadeMedida" column="UNIDADE_MEDIDA" not-null="true"/>

        </class>

</hibernate-mapping>
Mauricio_Linhares

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?

R

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.

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {

	private static final SessionFactory sessionFactory;
	
	static {
		try { 
			Configuration cfg = new Configuration();
			sessionFactory = cfg.configure().buildSessionFactory();
		} catch (Throwable ex) {
			ex.printStackTrace(System.out);
			throw new ExceptionInInitializerError(ex);
		}
	}
	
	public static Session getSession() throws HibernateException {
		return sessionFactory.openSession();
	}	

	public static void excluir(Object objeto) {
		Session session = getSession();
		Transaction transacao = session.beginTransaction();
		try{
			session.delete(objeto);
			transacao.commit();
		} finally {
			session.close();
		}
	}	
	
	public static void salvar(Object objeto) {
		Session session = HibernateUtil.getSession();
		Transaction transacao = session.beginTransaction();
		try {
			session.saveOrUpdate(objeto);
			transacao.commit();
		} finally{
		session.close();
		}
	}	
	
}
Mauricio_Linhares

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.

R

Nesse exemplo estou usando apenas o método getSession da classe HibernateUtil.

public static Session getSession() throws HibernateException { return sessionFactory.openSession(); }

R

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.

R

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?

<idbag name="itens" lazy="true" cascade="all-delete-orphan" table="ITEM_PECA_ESTRUTURAL"> <collection-id type="integer" column="ITEM_PECA_ESTRUTURAL_ID"> <generator class="sequence"> <param name="sequence"> ITEM_PECA_ESTRUTURAL_GEN </param> </generator> </collection-id> <key column="PECA_ESTRUTURAL_ID" not-null="true" /> <composite-element class="src.model.ItemPecaEstrutural"> <property name="quantidade" /> <property name="total" /> <many-to-one name="descricaoMaterial" column="DESCRICAO_MATERIAL_ID" /> </composite-element> </idbag>

R

Fiz a modificação para usar apenas 1 seção e 1 transação. Mas deu o erro abaixo, ao fazer o segundo load.

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
Mauricio_Linhares

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.

R

Fiz isso nesse código acima. O erro foi gerado do mesmo jeito, quando acontece o trans.commit().

_fs
R

Veja os parâmetros do c3p0 que coloco:

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

R

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.

_fs

tenta tirar o cp30 para testar.

R

Oi, tirei e funcionou.
Isso que estou fazendo não seria algo muito corriqueiro para estar dando problema?

_fs

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.

R

Atualizei para Hibernate 3.0.5 e funcionou normalmente com o pool. Já é a segunda vez que perco muito tempo pensando que fiz algo errado e que foi resolvido atualizando o hibernate. Na versão 3.0.5 do hibernate, o c3p0 está atualizado.

Eu nunca li documentação do pool e nem do driver. Para falar a verdade, eu não sei muito bem como funciona esse “tal” pool. Só uso porque li no livro Hibernate in Action que isso é altamente recomendável e que uma boa solução open source de pool é o c3p0.

Veja minha configuração. Tem algo que eu deveria mudar?

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.connection.lc_ctype = WIN1252
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

Spool

Tava dando uma lina nese tópico e achei legal postar.
Eu também tenho uma aplicação desktop com swing, e eu utilizo ThreadLocal pra carregar as sessões.

Olha ai um exemplo de classe de conexão:

public class ConnectionFactory {
    
    private static final SessionFactory sessionFactory;
    private static final ThreadLocal<Session> threadLocal =
            new ThreadLocal<Session>();
    
    static {
        
        try {
            sessionFactory = new AnnotationConfiguration().configure(
                    "hibernate.cfg.xml").buildSessionFactory();
        } catch (Throwable t) {
            throw new ExceptionInInitializerError(t);
        }
        
    }
    
    public static Session getInstance() {
        Session session = (Session) threadLocal.get();
        session = sessionFactory.openSession();
        threadLocal.set(session);
        return session;
    }
    
}

e para chamar a instância é só fazer assim:

Session session = ConnectionFactory.getInstance();

Até!

Criado 27 de maio de 2005
Ultima resposta 23 de nov. de 2007
Respostas 21
Participantes 4