Problema ao deletar objeto collection com hibernate cascade

2 respostas
N

Bom dia, sou iniciante em hibernate e estou com um problema na relação entre duas classes, em uma delas eu tenho um objeto pagina que tem relação com uma collection de objetos de grupo de questões, o problema é quando eu deleto o objeto pagina ele não deleta os objetos grupos ligados à página pois a relação com a chave estrangeira impede o deletar em cascata, alguém pode me ajudar?
aqui vão as classes:

classe página:

@Entity  
@Table(name="Pagina")  
public class Pagina {  
     
   @Id   
   @SequenceGenerator(name="GEN_PAGINA",sequenceName="SEQ_PAGINA")  
   @GeneratedValue(generator = "GEN_PAGINA")  
   @Column(name="idPagina", nullable=false, unique=true)  
   private Long idPagina;  
     
   @Column  
   private int status;     
     
   @Column  
   private String imagePath;     
     
   @Column  
   private int page_number;  
  
   @ManyToOne(fetch=FetchType.EAGER)  
    @JoinColumn(name="parent", updatable=true, insertable=true)  
    @Fetch(FetchMode.JOIN)  
    @Cascade(org.hibernate.annotations.CascadeType.ALL)  
    private Formulario parent;  
     
  @OneToMany(mappedBy="page", fetch=FetchType.LAZY )
    @Cascade({org.hibernate.annotations.CascadeType.ALL,org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
    @JoinColumn(name="page")
    @LazyCollection(LazyCollectionOption.FALSE)  
   private List<GrupoDeQuestoes> questiongroup = new ArrayList<GrupoDeQuestoes>();  
     
   @OneToMany(mappedBy="page", fetch=FetchType.LAZY)  
    @Cascade(org.hibernate.annotations.CascadeType.ALL)  
    @LazyCollection(LazyCollectionOption.FALSE)     
   private List<Questao> question = new ArrayList<Questao>();

classe Grupo_de _Questoes

@Entity  
@Table(name="Grupo_De_Questoes")  
public class GrupoDeQuestoes  {  
   @Id   
   @SequenceGenerator(name="GEN_GRUPO_QUESTAO",sequenceName="SEQ_GRUPO_QUESTAO")  
   @GeneratedValue(generator = "GEN_GRUPO_QUESTAO")  
   @Column(nullable=false, unique=true)  
   private Long idGrupo;  
  
   @OneToMany(mappedBy="questionGroup", fetch=FetchType.LAZY)  
    @Cascade(org.hibernate.annotations.CascadeType.ALL)  
    @LazyCollection(LazyCollectionOption.FALSE)     
    private List<Questao> question =  new ArrayList<Questao>();  
     
   @ManyToOne(fetch=FetchType.EAGER)  
    @JoinColumn(name="page")  
    @Fetch(FetchMode.JOIN)  
    @Cascade(CascadeType.ALL)  
   private Pagina page;  
     
   @OneToMany(mappedBy="questionGroup", fetch=FetchType.LAZY)  
    @Cascade(org.hibernate.annotations.CascadeType.ALL)  
    @LazyCollection(LazyCollectionOption.FALSE)     
    private List<GrupoDeQuestoes> listQuestionGroup = new ArrayList<GrupoDeQuestoes>();  
  
   @ManyToOne(fetch=FetchType.EAGER)  
    @JoinColumn(name="questionGroup", updatable=true, insertable=true)  
    @Fetch(FetchMode.JOIN)  
    @Cascade(CascadeType.ALL)  
   private GrupoDeQuestoes questionGroup;  
     
     
   @Column  
   private boolean selected;  
     
   @Column  
   private int status;  
  
   @Column  
   private int number;

e o erro que é gerado:

9:49:38,586  WARN JDBCExceptionReporter:100 - SQL Error: 0, SQLState: 23503  
09:49:38,590 ERROR JDBCExceptionReporter:101 - Entrada em lote 0 delete from Pagina where idPagina='1' foi abortada. Chame getNextException para ver a causa.  
09:49:38,591  WARN JDBCExceptionReporter:100 - SQL Error: 0, SQLState: 23503  
09:49:38,591 ERROR JDBCExceptionReporter:101 - ERRO: atualização ou exclusão em tabela "pagina" viola restrição de chave estrangeira "fkab9858433fe08e33" em "grupo_de_questoes"  
  Detalhe: Chave (idpagina)=(1) ainda é referenciada pela tabela "grupo_de_questoes".  
09:49:38,593 ERROR AbstractFlushingEventListener:324 - 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:94)  
   at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)  
   at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)  
   at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:114)  
   at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:109)  
   at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:244)  
   at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2507)  
   at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2725)  
   at org.hibernate.action.EntityDeleteAction.execute(EntityDeleteAction.java:97)  
   at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)  
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)  
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:172)  
   at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)  
   at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)  
   at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)  
   at org.springframework.orm.hibernate3.HibernateAccessor.flushIfNecessary(HibernateAccessor.java:390)  
   at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:407)  
   at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)  
   at org.springframework.orm.hibernate3.HibernateTemplate.delete(HibernateTemplate.java:837)  
   at org.springframework.orm.hibernate3.HibernateTemplate.delete(HibernateTemplate.java:833)  
   at br.com.illumeo.datatab.infrastructure.dao.DAO.delete(DAO.java:50)  
   at br.com.illumeo.datatab.infrastructure.util.ConvertToObject.delete(ConvertToObject.java:292)  
   at teste.testaRecuperaObjeto.main(testaRecuperaObjeto.java:67)  
   at br.com.illumeo.datatab.presentation.Principal$2.actionPerformed(Principal.java:78)  
   at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)  
   at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)  
   at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)  
   at javax.swing.DefaultButtonModel.setPressed(Unknown Source)  
   at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)  
   at java.awt.Component.processMouseEvent(Unknown Source)  
   at javax.swing.JComponent.processMouseEvent(Unknown Source)  
   at java.awt.Component.processEvent(Unknown Source)  
   at java.awt.Container.processEvent(Unknown Source)  
   at java.awt.Component.dispatchEventImpl(Unknown Source)  
   at java.awt.Container.dispatchEventImpl(Unknown Source)  
   at java.awt.Component.dispatchEvent(Unknown Source)  
   at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)  
   at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)  
   at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)  
   at java.awt.Container.dispatchEventImpl(Unknown Source)  
   at java.awt.Window.dispatchEventImpl(Unknown Source)  
   at java.awt.Component.dispatchEvent(Unknown Source)  
   at java.awt.EventQueue.dispatchEvent(Unknown Source)  
   at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)  
   at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)  
   at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)  
   at java.awt.EventDispatchThread.pumpEvents(Unknown Source)  
   at java.awt.EventDispatchThread.pumpEvents(Unknown Source)  
   at java.awt.EventDispatchThread.run(Unknown Source)  
Caused by: java.sql.BatchUpdateException: Entrada em lote 0 delete from Pagina where idPagina='1' foi abortada. Chame getNextException para ver a causa.  
   at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2569)  
   at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1796)  
   at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:407)  
   at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2708)  
   at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)  
   at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)  
   ... 46 more  
Exception in thread "AWT-EventQueue-0" org.springframework.dao.DataIntegrityViolationException: Could not execute JDBC batch update; SQL [delete from Pagina where idPagina=?]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update  
   at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:637)  
   at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)  
   at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:411)  
   at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)  
   at org.springframework.orm.hibernate3.HibernateTemplate.delete(HibernateTemplate.java:837)  
   at org.springframework.orm.hibernate3.HibernateTemplate.delete(HibernateTemplate.java:833)  
   at br.com.illumeo.datatab.infrastructure.dao.DAO.delete(DAO.java:50)  
   at br.com.illumeo.datatab.infrastructure.util.ConvertToObject.delete(ConvertToObject.java:292)  
   at teste.testaRecuperaObjeto.main(testaRecuperaObjeto.java:67)  
   at br.com.illumeo.datatab.presentation.Principal$2.actionPerformed(Principal.java:78)  
   at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)  
   at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)  
   at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)  
   at javax.swing.DefaultButtonModel.setPressed(Unknown Source)  
   at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)  
   at java.awt.Component.processMouseEvent(Unknown Source)  
   at javax.swing.JComponent.processMouseEvent(Unknown Source)  
   at java.awt.Component.processEvent(Unknown Source)  
   at java.awt.Container.processEvent(Unknown Source)  
   at java.awt.Component.dispatchEventImpl(Unknown Source)  
   at java.awt.Container.dispatchEventImpl(Unknown Source)  
   at java.awt.Component.dispatchEvent(Unknown Source)  
   at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)  
   at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)  
   at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)  
   at java.awt.Container.dispatchEventImpl(Unknown Source)  
   at java.awt.Window.dispatchEventImpl(Unknown Source)  
   at java.awt.Component.dispatchEvent(Unknown Source)  
   at java.awt.EventQueue.dispatchEvent(Unknown Source)  
   at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)  
   at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)  
   at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)  
   at java.awt.EventDispatchThread.pumpEvents(Unknown Source)  
   at java.awt.EventDispatchThread.pumpEvents(Unknown Source)  
   at java.awt.EventDispatchThread.run(Unknown Source)  
Caused by: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update  
   at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94)  
   at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)  
   at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)  
   at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:114)  
   at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:109)  
   at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:244)  
   at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2507)  
   at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2725)  
   at org.hibernate.action.EntityDeleteAction.execute(EntityDeleteAction.java:97)  
   at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)  
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)  
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:172)  
   at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)  
   at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)  
   at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)  
   at org.springframework.orm.hibernate3.HibernateAccessor.flushIfNecessary(HibernateAccessor.java:390)  
   at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:407)  
   ... 32 more  
Caused by: java.sql.BatchUpdateException: Entrada em lote 0 delete from Pagina where idPagina='1' foi abortada. Chame getNextException para ver a causa.  
   at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2569)  
   at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1796)  
   at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:407)  
   at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2708)  
   at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)  
   at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)  
   ... 46 more

2 Respostas

Super_Fabio

olha eu acho que você deve excluir primeiro os objetos que estão relacionados com a tabela pai , para excluir você deve primeiro excluir pela tabela filho , eu pelos menos acho que é isso.

N

Bom pessoal, depois de muito pesquisar descobri a solução, na vdd Fabio as notações do hibernate já deveriam ter feito isso pra mim qdo setei elas pra cascade.ALL, mas foi só colocar outra notação @ONDELETE que funcionou, aqui vai a solução obrigado pela resposta

public class Pagina {
	
	@Id 
	@SequenceGenerator(name="GEN_PAGINA",sequenceName="SEQ_PAGINA")
	@GeneratedValue(generator = "GEN_PAGINA")
	@Column(name="idPagina", nullable=false, unique=true)
	private Long idPagina;
	
	@Column
	private int status;	
	
	@Column
	private String imagePath;	
	
	@Column//(nullable=false, unique=true)
	private int page_number;

	@ManyToOne(fetch=FetchType.EAGER)
    @JoinColumn(name="parent", updatable=true, insertable=true)
    @Fetch(FetchMode.JOIN)
    @Cascade(org.hibernate.annotations.CascadeType.ALL)
    private Formulario parent;
	
	@OneToMany(mappedBy="page", fetch=FetchType.LAZY,cascade= javax.persistence.CascadeType.ALL )
    @Cascade({org.hibernate.annotations.CascadeType.ALL,org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
    @LazyCollection(LazyCollectionOption.FALSE)  
    @OnDelete(action= OnDeleteAction.CASCADE)
	private List<GrupoDeQuestoes> questiongroup = new ArrayList<GrupoDeQuestoes>();
	
	@OneToMany(mappedBy="page", fetch=FetchType.LAZY)
    @Cascade({org.hibernate.annotations.CascadeType.ALL, CascadeType.DELETE_ORPHAN})
    @LazyCollection(LazyCollectionOption.FALSE)   
    @OnDelete(action= OnDeleteAction.CASCADE)
	private List<Questao> question = new ArrayList<Questao>();

e na classe Grupo_de_Questoes fica normal

@Entity
@Table(name="Grupo_De_Questoes")
public class GrupoDeQuestoes  {
	@Id 
	@SequenceGenerator(name="GEN_GRUPO_QUESTAO",sequenceName="SEQ_GRUPO_QUESTAO")
	@GeneratedValue(generator = "GEN_GRUPO_QUESTAO")
	@Column(nullable=false, unique=true)
	private Long idGrupo;

	@OneToMany(mappedBy="questionGroup", fetch=FetchType.LAZY)
    @Cascade(org.hibernate.annotations.CascadeType.ALL)
    @LazyCollection(LazyCollectionOption.FALSE) 
    @OnDelete(action= OnDeleteAction.CASCADE)
 	private List<Questao> question =  new ArrayList<Questao>();
	
	@ManyToOne(fetch=FetchType.EAGER,cascade=javax.persistence.CascadeType.ALL)
    @JoinColumn(name="page", updatable=true, insertable=true)
    @Fetch(FetchMode.JOIN)
    @Cascade({CascadeType.ALL, CascadeType.DELETE_ORPHAN})
	private Pagina page;
	
	@OneToMany(mappedBy="questionGroup",fetch=FetchType.LAZY)
	@Cascade(org.hibernate.annotations.CascadeType.ALL)
    @LazyCollection(LazyCollectionOption.FALSE)   
    @OnDelete(action= OnDeleteAction.CASCADE)
 	private List<GrupoDeQuestoes> listQuestionGroup = new ArrayList<GrupoDeQuestoes>();

	@ManyToOne(fetch=FetchType.EAGER)
    @JoinColumn(name="questionGroup", updatable=true, insertable=true)
    @Fetch(FetchMode.JOIN)
    @Cascade(CascadeType.ALL)
    
	private GrupoDeQuestoes questionGroup;
Criado 2 de dezembro de 2011
Ultima resposta 5 de dez. de 2011
Respostas 2
Participantes 2