Hibernate - Erro ao remover dados

4 respostas
Trebloc

Olá todos.

Bom, estou tendo um problema aqui com um pequeno programa de Agenda Telefônica que estou fazendo, que só possui duas entidades: Contato e TelefoneContato. No banco de dados, são representadas pelas tabelas Contact e Contact_phone, existindo também a tabela associativa Contact_has_Contact_phone.

Ao inserir e atualizar os contatos, tudo está ocorrendo normalmente, porém ao tentar excluir qualquer contato, ele às vezes realmente o remove, mas às vezes também ocorre essa exceção (com a exclusão ocorrendo ou não):

04/06/2010 19:16:32 org.hibernate.util.JDBCExceptionReporter logExceptions
WARNING: SQL Error: 0, SQLState: null
04/06/2010 19:16:32 org.hibernate.util.JDBCExceptionReporter logExceptions
SEVERE: Entrada em lote 0 delete from public.Contact_Phone where Cd_contact_phone=1250 foi abortada. Chame getNextException para ver a causa.
04/06/2010 19:16:32 org.hibernate.util.JDBCExceptionReporter logExceptions
WARNING: SQL Error: 0, SQLState: 23503
04/06/2010 19:16:32 org.hibernate.util.JDBCExceptionReporter logExceptions
SEVERE: ERRO: atualização ou exclusão em tabela "contact_phone" viola restrição de chave estrangeira "contact_has_contact_phone_contact_phone_cd_contact_phone_fkey" em "contact_has_contact_phone"
  Detalhe: Chave (cd_contact_phone)=(1250) ainda é referenciada pela tabela "contact_has_contact_phone".
04/06/2010 19:16:32 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.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:92)
        at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:87)
        at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:222)
        at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2479)
        at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2697)
        at org.hibernate.action.EntityDeleteAction.execute(EntityDeleteAction.java:74)
        at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:234)
        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 com.gmail.thcolbert.agendatelefonica.database.Repository.remove(Repository.java:132)
        at com.gmail.thcolbert.agendatelefonica.gui.MainJFrame.removeContact(MainJFrame.java:425)
        at com.gmail.thcolbert.agendatelefonica.gui.MainJFrame.deleteSelectedContactMenuItemActionPerformed(MainJFrame.java:238)
        at com.gmail.thcolbert.agendatelefonica.gui.MainJFrame.access$300(MainJFrame.java:24)
        at com.gmail.thcolbert.agendatelefonica.gui.MainJFrame$4.actionPerformed(MainJFrame.java:131)
        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.AbstractButton.doClick(AbstractButton.java:357)
        at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:1225)
        at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:1266)
        at java.awt.Component.processMouseEvent(Component.java:6263)
        at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
        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.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.Contact_Phone where Cd_contact_phone=1250 foi abortada. Chame getNextException para ver a causa.
        at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2537)
        at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1328)
        at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:351)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2674)
        at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
        at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
        ... 46 more
com.gmail.thcolbert.agendatelefonica.database.RepositoryException: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
        at com.gmail.thcolbert.agendatelefonica.database.Repository.remove(Repository.java:137)
        at com.gmail.thcolbert.agendatelefonica.gui.MainJFrame.removeContact(MainJFrame.java:425)
        at com.gmail.thcolbert.agendatelefonica.gui.MainJFrame.deleteSelectedContactMenuItemActionPerformed(MainJFrame.java:238)
        at com.gmail.thcolbert.agendatelefonica.gui.MainJFrame.access$300(MainJFrame.java:24)
        at com.gmail.thcolbert.agendatelefonica.gui.MainJFrame$4.actionPerformed(MainJFrame.java:131)
        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.AbstractButton.doClick(AbstractButton.java:357)
        at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:1225)
        at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:1266)
        at java.awt.Component.processMouseEvent(Component.java:6263)
        ...

Acredito que seja algum problema no mapeamento da relação entre as classes, seria isso?

Contact.java
@Entity
@Table(name="Contact", schema="public")
@SequenceGenerator(name="contact_cd_contact_seq",
    sequenceName="contact_cd_contact_seq")
public class Contact implements Cloneable, Serializable
{
    ...

    /** Todos os números de telefone do contato. */
    @ManyToMany(fetch=FetchType.EAGER, cascade=CascadeType.ALL)
    @JoinTable(name="Contact_has_Contact_phone", schema="public",
        joinColumns={@JoinColumn(name="Contact_Cd_Contact")},
        inverseJoinColumns={@JoinColumn(name="Contact_phone_Cd_Contact_phone")})
    private List<ContactPhone> contactPhones;
}
ContactPhone.java
@Entity
@Table(name="Contact_Phone", schema="public")
@SequenceGenerator(name="contact_phone_cd_contact_phone_seq",
    sequenceName="contact_phone_cd_contact_phone_seq")
public class ContactPhone implements Cloneable, Serializable
{
    ...

    /** Os contatos que possuem este número de telefone. */
    @ManyToMany(fetch=FetchType.LAZY, 
        cascade={CascadeType.MERGE, CascadeType.PERSIST},
        mappedBy="contactPhones")
    private Collection<Contact> contacts;
}

Obrigado desde já. :)

4 Respostas

vhmolinar

Ola
Você precisa deletar da tabela de relacionamento antes de deletar das relacionadas.

Abraços

Trebloc

Isso eu sei, se estivesse fazendo em SQL eu faria assim, mas o problema está sendo com o Hibernate…

vhmolinar

Tenta isso? http://www.guj.com.br/posts/list/67454.java

Se ainda assim não for issso que deseja usa HQL ou SQL mesmo :wink:

Trebloc

Decidi mudar o Many-to-Many para One-to-Many/Many-to-One e resolvi o problema. :stuck_out_tongue:

Mas o mistério do Many-to-Many ainda continua.

Criado 4 de junho de 2010
Ultima resposta 6 de jun. de 2010
Respostas 4
Participantes 2