-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: @ManyToMany delete cascade
PostPosted: Thu Nov 29, 2007 12:51 pm 
Newbie

Joined: Fri Feb 10, 2006 2:20 pm
Posts: 9
Hibernate version: core: 3.2.5.ga, annotations: 3.3.0.ga

I've search over the forum and even if there's lots of post on this subject, I didn't find any answer for my problem...

I have a bean with a many to many relation on itself.
When I delete a bean which is related to other beans, it cannot perform the delete because of a foreign key constraint violation:
org.hibernate.exception.ConstraintViolationException.

Code:
org.springframework.dao.DataIntegrityViolationException: Could not execute JDBC batch update; nested exception is org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
  at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:622)
  at org.springframework.orm.hibernate3.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:690)
  at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:566)
  at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:662)
  at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:632)
  at org.springframework.test.context.transaction.TransactionalTestExecutionListener.endTransaction(TransactionalTestExecutionListener.java:346)
  at org.springframework.test.context.transaction.TransactionalTestExecutionListener.afterTestMethod(TransactionalTestExecutionListener.java:199)
  at org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:340)
  at org.springframework.test.context.junit4.SpringMethodRoadie.runAfters(SpringMethodRoadie.java:351)
  at org.springframework.test.context.junit4.SpringMethodRoadie.runBeforesThenTestThenAfters(SpringMethodRoadie.java:262)
  at org.springframework.test.context.junit4.SpringMethodRoadie.runWithRepetitions(SpringMethodRoadie.java:234)
  at org.springframework.test.context.junit4.SpringMethodRoadie.runTest(SpringMethodRoadie.java:204)
  at org.springframework.test.context.junit4.SpringMethodRoadie.run(SpringMethodRoadie.java:146)
  at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:151)
  at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
  at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
  at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
  at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
  at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
  at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
  at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: 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 org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:558)
  ... 22 more
Caused by: java.sql.BatchUpdateException: Cannot delete or update a parent row: a foreign key constraint fails (`obs/test_test`, CONSTRAINT `FK5C8CE6BFAAF990FE` FOREIGN KEY (`relatedtests_id`) REFERENCES `test` (`id`))
  at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1213)
  at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:912)
  at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
  at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
  at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
  ... 30 more


Here is my test bean :

Code:
@Entity
public class Test implements Serializable {

  private static final long serialVersionUID = 1L;

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;

  @ManyToMany
  private Set<Test> relatedTests;

  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public Set<Test> getRelatedTests() {
    if (relatedTests == null) relatedTests = new HashSet<Test>();
    return relatedTests;
  }

  public void setRelatedTests(Set<Test> relatedTests) {
    this.relatedTests = relatedTests;
  }

  public void addRelatedTest(Test test) {
    if (getRelatedTests().add(test)) test.getRelatedTests().add(this);
  }

  public void removeRelatedTest(Test test) {
    if (getRelatedTests().remove(test)) test.getRelatedTests().remove(this);
  }

  @Override
  public boolean equals(final Object other) {
    if (!(other instanceof Test)) return false;
    Test castOther = (Test) other;
    return new EqualsBuilder().append(id, castOther.id).isEquals();
  }

  @Override
  public int hashCode() {
    return new HashCodeBuilder().append(id).toHashCode();
  }

}


Test case:
Code:
[...]
@Test
@Rollback(false)
public void createTest() {
  Test t1 = new Test();
  genericDao.saveOrUpdate(t1);

  Test t2 = new Test();
  genericDao.saveOrUpdate(t2);

  t1.addRelatedTest(t2);

  genericDao.saveOrUpdate(t1);
}

@Test
@Rollback(false)
public void deleteTest() {
  Test test = genericDao.findAll(Test.class).get(0);
  genericDao.delete(test);
}
[...]


The only work-around I found is to create an Interceptor that clear the relation beofre a bean is deleted :
Code:
public class TestInterceptor extends EmptyInterceptor {

  @Override
  public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
    if (entity instanceof Test) {
      Test test = (Test) entity;
      for (Test related : test.getRelatedTests()) {
        test.removeRelatedTest(related);
      }
    }
  }

}



I'm sure there's a way to avoid this Interceptor... I don't undersatnd with this many to many relation cannot be deleted on cascade :-(
I've also tried with @Cascade but it does not work neither...

Thanks for your help.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 04, 2007 6:09 am 
Beginner
Beginner

Joined: Sun Jul 31, 2005 6:15 pm
Posts: 28
hello can you send the table definition.

_________________
Michael Courcy


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.