persistence@glassfish.java.net

Re: cascaded remove failure on many-to-many relationship

From: Christopher Delahunt <christopher.delahunt_at_oracle.com>
Date: Fri, 30 Jun 2006 09:47:39 -0400

Hello Wonseok,

Looks like you have the cascade=REMOVE set on the Team->Player relationship, but do you also have Player->Team set to cascade remove? If not, that would cause this issue.

Problem is that you are removing Team T6 which cascades to P9, P21, and P24, but Team T2 still has a reference to P9. If you are going to remove Player P9, all other objects not being removed must have their references to it set to null, or they too must be removed.

Best Regards,
Chris
  ----- Original Message -----
  From: Wonseok Kim
  To: persistence_at_glassfish.dev.java.net
  Sent: Friday, June 30, 2006 7:26 AM
  Subject: cascaded remove failure on many-to-many relationship


  target: GlassFish v2 b08, Derby with java2db(ddl-generation)

  When running Java EE 5 tutorial ejb/roster sample application on trunk build, removing entities throws Exception - a violation of foreign key constraint. But GlassFish v1 FCS has no problem.

  Team and Player entity has bidirectional ManyToMany relationship with cascade=REMOVE.

  Client does something like following:
  P# is Player id,T# is Team id

              request.addPlayer("P9", "T2");

              request.addPlayer("P24", "T6");
              request.addPlayer("P21", "T6");
              request.addPlayer("P9", "T6");

              System.out.println("Removing team T6.");
              request.removeTeam("T6");

  <SERVER LOG>
  removeTeam
  DELETE FROM EJB_ROSTER_TEAM_PLAYER WHERE (TEAM_ID = ?)
          bind => [T6]|#]
  DELETE FROM EJB_ROSTER_TEAM WHERE (ID = ?)
          bind => [T6]|#]
  DELETE FROM EJB_ROSTER_PLAYER WHERE (ID = ?)
          bind => [P9]|#]
   
  Local Exception Stack:
  Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2006.6 (Build 060608)): oracle.toplink.essentials.exceptions.DatabaseException
  Internal Exception: org.apache.derby.client.am.SqlException: DELETE on table 'EJB_ROSTER_PLAYER' caused a violation of foreign key constraint 'JBRSTRTMPLYERPLYRD' for key (P9). The statement has been rolled back.Error Code: -1
  Call:DELETE FROM EJB_ROSTER_PLAYER WHERE (ID = ?)
          bind => [P9]
  Query:DeleteObjectQuery(roster.entity.Player_at_1bb121f)
          at oracle.toplink.essentials.exceptions.DatabaseException.sqlException (DatabaseException.java:295)
          at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:639)
          at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeNoSelect (DatabaseAccessor.java:688)
          at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:477)
          at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeCall (DatabaseAccessor.java:437)
          at oracle.toplink.essentials.internal.sessions.AbstractSession.executeCall(AbstractSession.java:675)
          at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.executeCall (DatasourceCallQueryMechanism.java:213)
          at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:199)
          at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.deleteObject (DatasourceCallQueryMechanism.java:190)
          at oracle.toplink.essentials.internal.queryframework.StatementQueryMechanism.deleteObject(StatementQueryMechanism.java:115)
          at oracle.toplink.essentials.queryframework.DeleteObjectQuery.executeDatabaseQuery (DeleteObjectQuery.java:132)
          at oracle.toplink.essentials.queryframework.DatabaseQuery.execute(DatabaseQuery.java:609)
          at oracle.toplink.essentials.queryframework.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java :536)
          at oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:123)
          at oracle.toplink.essentials.queryframework.DeleteObjectQuery.executeInUnitOfWorkObjectLevelModifyQuery (DeleteObjectQuery.java:95)
          at oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:95)
          at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.internalExecuteQuery (UnitOfWorkImpl.java:2218)
          at oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:937)
          at oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery (AbstractSession.java:894)
          at oracle.toplink.essentials.internal.sessions.CommitManager.deleteAllObjects(CommitManager.java:322)
          at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.commitToDatabase (UnitOfWorkImpl.java:1033)
          at oracle.toplink.essentials.internal.ejb.cmp3.base.RepeatableWriteUnitOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:353)
          at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet (UnitOfWorkImpl.java:1112)
          at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.issueSQLbeforeCompletion(UnitOfWorkImpl.java:2428)
          at oracle.toplink.essentials.internal.ejb.cmp3.base.RepeatableWriteUnitOfWork.issueSQLbeforeCompletion (RepeatableWriteUnitOfWork.java:177)
          at oracle.toplink.essentials.transaction.AbstractSynchronizationListener.beforeCompletion(AbstractSynchronizationListener.java:116)
          at oracle.toplink.essentials.transaction.JTASynchronizationListener.beforeCompletion (JTASynchronizationListener.java:76)
          at com.sun.ejb.containers.ContainerSynchronization.beforeCompletion(ContainerSynchronization.java:154)
          at com.sun.enterprise.distributedtx.J2EETransaction.commit( J2EETransaction.java:395)
          at com.sun.enterprise.distributedtx.J2EETransactionManagerOpt.commit(J2EETransactionManagerOpt.java:357)
          at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java :3653)
          at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:3431)
          at com.sun.ejb.containers.StatefulSessionContainer.postInvokeTx(StatefulSessionContainer.java:1292)
          at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1247)
          at com.sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.java:197)
          at com.sun.ejb.containers.EJBObjectInvocationHandlerDelegate.invoke (EJBObjectInvocationHandlerDelegate.java:67)
          at $Proxy43.removeTeam(Unknown Source)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
          at java.lang.reflect.Method.invoke(Method.java:585)
          at com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie._invoke (ReflectiveTie.java:121)
          at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(CorbaServerRequestDispatcherImpl.java:650)
          at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch (CorbaServerRequestDispatcherImpl.java:193)
          at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1705)
          at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest (CorbaMessageMediatorImpl.java:1565)
          at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleInput(CorbaMessageMediatorImpl.java:947)
          at com.sun.corba.ee.impl.protocol.giopmsgheaders.RequestMessage_1_2.callback (RequestMessage_1_2.java:178)
          at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:717)
          at com.sun.corba.ee.impl.transport.SocketOrChannelConnectionImpl.dispatch (SocketOrChannelConnectionImpl.java:473)
          at com.sun.corba.ee.impl.transport.SocketOrChannelConnectionImpl.doWork(SocketOrChannelConnectionImpl.java:1270)
          at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run (ThreadPoolImpl.java:479)
  Caused by: org.apache.derby.client.am.SqlException: DELETE on table 'EJB_ROSTER_PLAYER' caused a violation of foreign key constraint 'JBRSTRTMPLYERPLYRD' for key (P9). The statement has been rolled back.
          at org.apache.derby.client.am.Statement.completeExecute(Unknown Source)
          at org.apache.derby.client.net.NetStatementReply.parseEXCSQLSTTreply(Unknown Source)
          at org.apache.derby.client.net.NetStatementReply.readExecute (Unknown Source)
          at org.apache.derby.client.net.StatementReply.readExecute(Unknown Source)
          at org.apache.derby.client.net.NetPreparedStatement.readExecute_(Unknown Source)
          at org.apache.derby.client.am.PreparedStatement.readExecute (Unknown Source)
          at org.apache.derby.client.am.PreparedStatement.flowExecute(Unknown Source)
          at org.apache.derby.client.am.PreparedStatement.executeUpdateX(Unknown Source)
          at org.apache.derby.client.am.PreparedStatement.executeUpdate (Unknown Source)
          at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:632)
          ... 50 more
  |#]

  Cascaded remove should trigger more DELETE statements, but it didn't.
  Is it known issue? Or shall I file an issue for this?

  --
  Wonseok Kim
  Senior Developer, TmaxSoft