Hibernate - delete

9 respostas
R

Olá pessoal,
estou com um problema e que não estou conseguindo resolver. Utilizo hibernate e quando tento remover um item de uma tabela que possui referencia em outra tabela a remoção não é permitida, até aí td bem, o problema é que consigo tratar a exception já que antes dela são apresentadas várias outras exceptions.

Código para deletar:

Marca marca = new Marca();
        marca = (Marca) cbMarca.getSelectedItem();
        DaoFactory factory = DaoFactory.getInstance();
        try {
            factory.beginTransaction();
            Dao dao = factory.getDao(Marca.class);
            
            dao.remove(marca);            
            factory.commit();
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        }

Erro gerado:

03/05/2010 15:34:03 org.hibernate.util.JDBCExceptionReporter logExceptions
WARNING: SQL Error: 0, SQLState: null
03/05/2010 15:34:03 org.hibernate.util.JDBCExceptionReporter logExceptions
SEVERE: Entrada em lote 0 delete from public.marca where marca_id=62 foi abortada. Chame getNextException para ver a causa.
03/05/2010 15:34:03 org.hibernate.util.JDBCExceptionReporter logExceptions
WARNING: SQL Error: 0, SQLState: 23503
03/05/2010 15:34:03 org.hibernate.util.JDBCExceptionReporter logExceptions
SEVERE: ERROR: update or delete on table "marca" violates foreign key constraint "fkproduto_marca_id" on table "produto"
  Detalhe: Key (marca_id)=(62) is still referenced from table "produto".
03/05/2010 15:34:03 org.hibernate.event.def.AbstractFlushingEventListener performExecutions
SEVERE: Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
        at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
        at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
        at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:237)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:146)
        at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
        at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
        at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
        at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
        at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
        at dao.DaoFactory.commit(DaoFactory.java:29)
        at frame.NewJDialog.jButton1ActionPerformed(NewJDialog.java:107)
        at frame.NewJDialog.access$000(NewJDialog.java:27)
        at frame.NewJDialog$1.actionPerformed(NewJDialog.java:58)
        at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
        at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
        at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
        at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
        at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
        at java.awt.Component.processMouseEvent(Component.java:6263)
        at javax.swing.JComponent.processMouseEvent(JComponent.java:3255)
        at java.awt.Component.processEvent(Component.java:6028)
        at java.awt.Container.processEvent(Container.java:2041)
        at java.awt.Component.dispatchEventImpl(Component.java:4630)
        at java.awt.Container.dispatchEventImpl(Container.java:2099)
        at java.awt.Component.dispatchEvent(Component.java:4460)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4574)
        at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)
        at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
        at java.awt.Container.dispatchEventImpl(Container.java:2085)
        at java.awt.Window.dispatchEventImpl(Window.java:2475)
        at java.awt.Component.dispatchEvent(Component.java:4460)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:178)
        at java.awt.Dialog$1.run(Dialog.java:1045)
        at java.awt.Dialog$3.run(Dialog.java:1097)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.awt.Dialog.show(Dialog.java:1095)
        at java.awt.Component.show(Component.java:1563)
        at java.awt.Component.setVisible(Component.java:1515)
        at java.awt.Window.setVisible(Window.java:841)
        at java.awt.Dialog.setVisible(Dialog.java:985)
        at frame.NewJDialog$3.run(NewJDialog.java:132)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Caused by: java.sql.BatchUpdateException: Entrada em lote 0 delete from public.marca where marca_id=62 foi abortada. Chame getNextException para ver a causa.
Could not execute JDBC batch update
        at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2530)
        at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1317)
        at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:350)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2592)
        at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
        at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
        ... 50 more

Desde já agradeço e aguardo alguma dica.

9 Respostas

rogelgarcia

Faça isso primeiro pra descobrir qual é a exceçao lançada:

catch (Exception ex) { System.out.println(ex.getClass()+" "+ex.getMessage()); }

Sabendo qual é exceção correta… ao invés de dar catch(Exception e)… faça:

catch (HibernateException ex) {

Ou a exceção correta que for mostrada na mensagem… assim… vc terá os métodos corretos da exceção

ex.getCause()

ex.getTargetException()

ex.getXXX()

Aí vc ve qual é método que te dá a mensagem correta…

Talvez até o catch(Exception ex) chamando ex.getCause() dê certo… mas pela experiência que tenho com banco de dados, geralmente é necessário pegar a exceção correta…
Talvez até fazendo um ex.getCause()… e fazendo um cast para SQLException por exemplo: (SQLException)ex.getCause()

Debugar a exceção… também é uma boa…

R

Olá rogelgarcia, a classe da exception é esta: class org.hibernate.exception.ConstraintViolationException.
Fiz um teste executando o método de remover utilizando SQL no Dao e conseguir capturar e tratar a exceção utilizando o mesmo código que utilizo hj.
Mas o problema é que quando tento remover através do hibernate (session.delete(classe)) não consigo capturar porque junto com a exception ‘ConstraintViolationException’ aparecem vários outros erros que não consigo interromper causando falhas no aplicativo.
Só lembrando, a exception é gerada no commit do remove.

rogelgarcia

Vc chegou a fazer alguma alteraçao no seu código?

R

Apenas alterei o código no método remove do Dao para testar e comprovei que consigo capturar a exception quando uso SQL para remover.

rogelgarcia

E vc caputra a exceção e mesmo assim dá erro no programa?

R

Sim, se capturo a exception e coloco para visualisar (getMessage()) aparece como na linha 67 do erro gerado que mostrei e mesmo assim aparecem vários erros antes como vc também pode ver.

ralphsilver

dá um merge antes de remover…

R

Só lembrando: o problema está quando tento remover algum objeto que está referenciado em outra tabela.

Se executar o merge antes do remove dá está mensagem:

“a different object with the same identifier value was already associated with the session:”

rogelgarcia

Talvez esteja acontecendo um printStackTrace… mas mesmo assim vc consiga capturar a exceção…

A mensagem é mostrada, mas o fluxo não é interrompido…

Se for isso, acho que talvez não tenha como mecher nessa mensagem…

Criado 1 de maio de 2010
Ultima resposta 4 de mai. de 2010
Respostas 9
Participantes 3