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