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
[code]
@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;
}[/code]
Obrigado desde já.