Re: [JBoss-user] sync-on-commit-only and cascade-delete
Andrew, could you create a simple testcase, please? Taking into account the description you gave, it shouldn't be hard to do. Thank you, alex Andrew May wrote: The Entity beans only have local interfaces. They are accessed via a Stateless Session bean which has transaction=Required for all methods. The only non-standard thing is that the get* methods are marked read-only in jboss.xml. Where I'm performing a delete it's a simple call to the session bean from a servlet - it locates the entity using the primary key and then calls remove(). All the related beans are packaged within the same JAR, which is deployed in an EAR as part of a much larger application. Because I'm running my own instance of the application there shouldn't be any concurrent access to the beans when I'm attempting these deletes. -Andrew Alexey Loubyansky wrote: Are there other beans involved in the tx? Something, causes synchronization. If all the CMP2 beans have sync-on-commit-only=true, then it shouldn't happen. alex Andrew May wrote: Alex, Thanks for your reply - my answers in-lined: -Andrew Alexey Loubyansky wrote: Hello, Andrew. my comments in-lined. Andrew May wrote: I'm having a problem trying to user sync-on-commit-only and cascade-delete with JBoss 3.2.1 (Sun JDK1.4.2, Solaris). We've got a number of related entities like this: LOGIN---IDENTITY | | LOGINPROPERTIES IDENTITYPROPERTIES login->identity, login->loginproperties & identity->identityproperties are 1-M relationships and are defined as cascade-delete. To be exact: LOGIN - IDENTITY: M-1 IDENTITY - IDENTITYPROPERTIES: 1-M LOGIN - LOGINPROPERTIES: 1-M correct? Yes (sorry) When we originally developed the application on JBoss 3.0 there wasn't (or I wasn't aware of it) a sync-on-commit-only option, so all our foreign keys are nullable, and also our properties foreign keys (loginid and identityid) are not part of the primary key of the properties because I don't think this was possible at the time either. The entities are actually using views on an Oracle database. For various reasons we need to keep data that has been deleted, so when a delete is performed a hidden state is changed and the records no longer appear in the view but still exist in the table. We're now developing an API for maintaining the data (previously any deletes were done directly in the database) and we're having to think about how the EJB remove() calls interact with the database and the views and the triggers that maintain the views. If sync-on-commit-only=false then as per the spec all the relationships are broken before the entities are deleted. This looks OK to the application and in the views, but the data in the tables that's kept has had all the relationships broken and is no longer useful. With sync-on-commit-only=false things work fine in the simple cases: If I guess, I meant sync-on-commit-only=true, right? Yes (sorry again - blame it on Friday afternoon) I delete a login, it is deleted as are it's properties (although I'm a bit surprised that the properties are deleted after the login). If I yes, it works that way. delete an identity that doesn't have any logins it works OK. However, if I delete an identity that has logins it fails: JDBCRemoveEntityCommand.Identity] Executing SQL: DELETE FROM ACS_IDENTITY WHERE identityid=? JDBCRemoveEntityCommand.Identity] Remove: Rows affected = 1 JDBCRemoveEntityCommand.Identity] Checking if already deleted: id100169city JDBCRemoveEntityCommand.Identity] Deleteing: id100169city JDBCRemoveEntityCommand.IdentityProperty] Executing SQL: DELETE FROM ACS_IDENTITYPROPERTY WHERE id=? JDBCRemoveEntityCommand.IdentityProperty] Remove: Rows affected = 1 JDBCRemoveEntityCommand.Identity] Checking if already deleted: id100169country JDBCRemoveEntityCommand.Identity] Deleteing: id100169country JDBCRemoveEntityCommand.IdentityProperty] Executing SQL: DELETE FROM ACS_IDENTITYPROPERTY WHERE id=? JDBCRemoveEntityCommand.IdentityProperty] Remove: Rows affected = 1 JDBCRemoveEntityCommand.Identity] Checking if already deleted: 4885910 JDBCRemoveEntityCommand.Identity] Deleteing: 4885910 JDBCLoadRelationCommand.Login] Executing SQL: SELECT id, name, value FROM ACS_LOGINPROPERTY WHERE (loginid=?) JDBCRemoveEntityCommand.Login] Executing SQL: DELETE FROM ACS_LOGIN WHERE loginid=? JDBCStoreEntityCommand.Login] Executing SQL: UPDATE ACS_LOGIN SET identityid=? WHERE loginid=? 2003-08-29 13:39:14,209 ERROR [org.jboss.ejb.plugins.LogInterceptor] TransactionRolledbackException, causedBy: javax.ejb.EJBException: Update failed. Expected one affected row: rowsAffected=0id=4885910 Looking at the last two statements, this is expected result. Does LoginProperties have sync-on-commit-only set also to true? Are all the beans have it as true? Because we're only using CMP2 for this set of related entities, I've been setting sync-on-commit-only=true globally i
Re: [JBoss-user] sync-on-commit-only and cascade-delete
The Entity beans only have local interfaces. They are accessed via a Stateless Session bean which has transaction=Required for all methods. The only non-standard thing is that the get* methods are marked read-only in jboss.xml. Where I'm performing a delete it's a simple call to the session bean from a servlet - it locates the entity using the primary key and then calls remove(). All the related beans are packaged within the same JAR, which is deployed in an EAR as part of a much larger application. Because I'm running my own instance of the application there shouldn't be any concurrent access to the beans when I'm attempting these deletes. -Andrew Alexey Loubyansky wrote: Are there other beans involved in the tx? Something, causes synchronization. If all the CMP2 beans have sync-on-commit-only=true, then it shouldn't happen. alex Andrew May wrote: Alex, Thanks for your reply - my answers in-lined: -Andrew Alexey Loubyansky wrote: Hello, Andrew. my comments in-lined. Andrew May wrote: I'm having a problem trying to user sync-on-commit-only and cascade-delete with JBoss 3.2.1 (Sun JDK1.4.2, Solaris). We've got a number of related entities like this: LOGIN---IDENTITY | | LOGINPROPERTIES IDENTITYPROPERTIES login->identity, login->loginproperties & identity->identityproperties are 1-M relationships and are defined as cascade-delete. To be exact: LOGIN - IDENTITY: M-1 IDENTITY - IDENTITYPROPERTIES: 1-M LOGIN - LOGINPROPERTIES: 1-M correct? Yes (sorry) When we originally developed the application on JBoss 3.0 there wasn't (or I wasn't aware of it) a sync-on-commit-only option, so all our foreign keys are nullable, and also our properties foreign keys (loginid and identityid) are not part of the primary key of the properties because I don't think this was possible at the time either. The entities are actually using views on an Oracle database. For various reasons we need to keep data that has been deleted, so when a delete is performed a hidden state is changed and the records no longer appear in the view but still exist in the table. We're now developing an API for maintaining the data (previously any deletes were done directly in the database) and we're having to think about how the EJB remove() calls interact with the database and the views and the triggers that maintain the views. If sync-on-commit-only=false then as per the spec all the relationships are broken before the entities are deleted. This looks OK to the application and in the views, but the data in the tables that's kept has had all the relationships broken and is no longer useful. With sync-on-commit-only=false things work fine in the simple cases: If I guess, I meant sync-on-commit-only=true, right? Yes (sorry again - blame it on Friday afternoon) I delete a login, it is deleted as are it's properties (although I'm a bit surprised that the properties are deleted after the login). If I yes, it works that way. delete an identity that doesn't have any logins it works OK. However, if I delete an identity that has logins it fails: JDBCRemoveEntityCommand.Identity] Executing SQL: DELETE FROM ACS_IDENTITY WHERE identityid=? JDBCRemoveEntityCommand.Identity] Remove: Rows affected = 1 JDBCRemoveEntityCommand.Identity] Checking if already deleted: id100169city JDBCRemoveEntityCommand.Identity] Deleteing: id100169city JDBCRemoveEntityCommand.IdentityProperty] Executing SQL: DELETE FROM ACS_IDENTITYPROPERTY WHERE id=? JDBCRemoveEntityCommand.IdentityProperty] Remove: Rows affected = 1 JDBCRemoveEntityCommand.Identity] Checking if already deleted: id100169country JDBCRemoveEntityCommand.Identity] Deleteing: id100169country JDBCRemoveEntityCommand.IdentityProperty] Executing SQL: DELETE FROM ACS_IDENTITYPROPERTY WHERE id=? JDBCRemoveEntityCommand.IdentityProperty] Remove: Rows affected = 1 JDBCRemoveEntityCommand.Identity] Checking if already deleted: 4885910 JDBCRemoveEntityCommand.Identity] Deleteing: 4885910 JDBCLoadRelationCommand.Login] Executing SQL: SELECT id, name, value FROM ACS_LOGINPROPERTY WHERE (loginid=?) JDBCRemoveEntityCommand.Login] Executing SQL: DELETE FROM ACS_LOGIN WHERE loginid=? JDBCStoreEntityCommand.Login] Executing SQL: UPDATE ACS_LOGIN SET identityid=? WHERE loginid=? 2003-08-29 13:39:14,209 ERROR [org.jboss.ejb.plugins.LogInterceptor] TransactionRolledbackException, causedBy: javax.ejb.EJBException: Update failed. Expected one affected row: rowsAffected=0id=4885910 Looking at the last two statements, this is expected result. Does LoginProperties have sync-on-commit-only set also to true? Are all the beans have it as true? Because we're only using CMP2 for this set of related entities, I've been setting sync-on-commit-only=true globally in standardjboss.xml. This is also where I've been turing on/off call-logging. at org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreEntityCommand.execute(JDBCStoreEntityCommand
Re: [JBoss-user] sync-on-commit-only and cascade-delete
Are there other beans involved in the tx? Something, causes synchronization. If all the CMP2 beans have sync-on-commit-only=true, then it shouldn't happen. alex Andrew May wrote: Alex, Thanks for your reply - my answers in-lined: -Andrew Alexey Loubyansky wrote: Hello, Andrew. my comments in-lined. Andrew May wrote: I'm having a problem trying to user sync-on-commit-only and cascade-delete with JBoss 3.2.1 (Sun JDK1.4.2, Solaris). We've got a number of related entities like this: LOGIN---IDENTITY | | LOGINPROPERTIES IDENTITYPROPERTIES login->identity, login->loginproperties & identity->identityproperties are 1-M relationships and are defined as cascade-delete. To be exact: LOGIN - IDENTITY: M-1 IDENTITY - IDENTITYPROPERTIES: 1-M LOGIN - LOGINPROPERTIES: 1-M correct? Yes (sorry) When we originally developed the application on JBoss 3.0 there wasn't (or I wasn't aware of it) a sync-on-commit-only option, so all our foreign keys are nullable, and also our properties foreign keys (loginid and identityid) are not part of the primary key of the properties because I don't think this was possible at the time either. The entities are actually using views on an Oracle database. For various reasons we need to keep data that has been deleted, so when a delete is performed a hidden state is changed and the records no longer appear in the view but still exist in the table. We're now developing an API for maintaining the data (previously any deletes were done directly in the database) and we're having to think about how the EJB remove() calls interact with the database and the views and the triggers that maintain the views. If sync-on-commit-only=false then as per the spec all the relationships are broken before the entities are deleted. This looks OK to the application and in the views, but the data in the tables that's kept has had all the relationships broken and is no longer useful. With sync-on-commit-only=false things work fine in the simple cases: If I guess, I meant sync-on-commit-only=true, right? Yes (sorry again - blame it on Friday afternoon) I delete a login, it is deleted as are it's properties (although I'm a bit surprised that the properties are deleted after the login). If I yes, it works that way. delete an identity that doesn't have any logins it works OK. However, if I delete an identity that has logins it fails: JDBCRemoveEntityCommand.Identity] Executing SQL: DELETE FROM ACS_IDENTITY WHERE identityid=? JDBCRemoveEntityCommand.Identity] Remove: Rows affected = 1 JDBCRemoveEntityCommand.Identity] Checking if already deleted: id100169city JDBCRemoveEntityCommand.Identity] Deleteing: id100169city JDBCRemoveEntityCommand.IdentityProperty] Executing SQL: DELETE FROM ACS_IDENTITYPROPERTY WHERE id=? JDBCRemoveEntityCommand.IdentityProperty] Remove: Rows affected = 1 JDBCRemoveEntityCommand.Identity] Checking if already deleted: id100169country JDBCRemoveEntityCommand.Identity] Deleteing: id100169country JDBCRemoveEntityCommand.IdentityProperty] Executing SQL: DELETE FROM ACS_IDENTITYPROPERTY WHERE id=? JDBCRemoveEntityCommand.IdentityProperty] Remove: Rows affected = 1 JDBCRemoveEntityCommand.Identity] Checking if already deleted: 4885910 JDBCRemoveEntityCommand.Identity] Deleteing: 4885910 JDBCLoadRelationCommand.Login] Executing SQL: SELECT id, name, value FROM ACS_LOGINPROPERTY WHERE (loginid=?) JDBCRemoveEntityCommand.Login] Executing SQL: DELETE FROM ACS_LOGIN WHERE loginid=? JDBCStoreEntityCommand.Login] Executing SQL: UPDATE ACS_LOGIN SET identityid=? WHERE loginid=? 2003-08-29 13:39:14,209 ERROR [org.jboss.ejb.plugins.LogInterceptor] TransactionRolledbackException, causedBy: javax.ejb.EJBException: Update failed. Expected one affected row: rowsAffected=0id=4885910 Looking at the last two statements, this is expected result. Does LoginProperties have sync-on-commit-only set also to true? Are all the beans have it as true? Because we're only using CMP2 for this set of related entities, I've been setting sync-on-commit-only=true globally in standardjboss.xml. This is also where I've been turing on/off call-logging. at org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreEntityCommand.execute(JDBCStoreEntityCommand.java:165) at org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager.storeEntity(JDBCStoreManager.java:649) at org.jboss.ejb.plugins.CMPPersistenceManager.storeEntity(CMPPersistenceManager.java:434) at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.storeEntity(CachedConnectionInterceptor.java:388) at org.jboss.ejb.EntityContainer.storeEntity(EntityContainer.java:702) at org.jboss.ejb.GlobalTxEntityMap.synchronizeEntities(GlobalTxEntityMap.java:163) at org.jboss.ejb.GlobalTxEntityMap$GlobalTxEntityMapCleanup.beforeCompletion(GlobalTxEntityMap.java:227) at org.jboss.tm.TransactionImpl.doBeforeCompletion(Trans
Re: [JBoss-user] sync-on-commit-only and cascade-delete
Alex, Thanks for your reply - my answers in-lined: -Andrew Alexey Loubyansky wrote: Hello, Andrew. my comments in-lined. Andrew May wrote: I'm having a problem trying to user sync-on-commit-only and cascade-delete with JBoss 3.2.1 (Sun JDK1.4.2, Solaris). We've got a number of related entities like this: LOGIN---IDENTITY | | LOGINPROPERTIES IDENTITYPROPERTIES login->identity, login->loginproperties & identity->identityproperties are 1-M relationships and are defined as cascade-delete. To be exact: LOGIN - IDENTITY: M-1 IDENTITY - IDENTITYPROPERTIES: 1-M LOGIN - LOGINPROPERTIES: 1-M correct? Yes (sorry) When we originally developed the application on JBoss 3.0 there wasn't (or I wasn't aware of it) a sync-on-commit-only option, so all our foreign keys are nullable, and also our properties foreign keys (loginid and identityid) are not part of the primary key of the properties because I don't think this was possible at the time either. The entities are actually using views on an Oracle database. For various reasons we need to keep data that has been deleted, so when a delete is performed a hidden state is changed and the records no longer appear in the view but still exist in the table. We're now developing an API for maintaining the data (previously any deletes were done directly in the database) and we're having to think about how the EJB remove() calls interact with the database and the views and the triggers that maintain the views. If sync-on-commit-only=false then as per the spec all the relationships are broken before the entities are deleted. This looks OK to the application and in the views, but the data in the tables that's kept has had all the relationships broken and is no longer useful. With sync-on-commit-only=false things work fine in the simple cases: If I guess, I meant sync-on-commit-only=true, right? Yes (sorry again - blame it on Friday afternoon) I delete a login, it is deleted as are it's properties (although I'm a bit surprised that the properties are deleted after the login). If I yes, it works that way. delete an identity that doesn't have any logins it works OK. However, if I delete an identity that has logins it fails: JDBCRemoveEntityCommand.Identity] Executing SQL: DELETE FROM ACS_IDENTITY WHERE identityid=? JDBCRemoveEntityCommand.Identity] Remove: Rows affected = 1 JDBCRemoveEntityCommand.Identity] Checking if already deleted: id100169city JDBCRemoveEntityCommand.Identity] Deleteing: id100169city JDBCRemoveEntityCommand.IdentityProperty] Executing SQL: DELETE FROM ACS_IDENTITYPROPERTY WHERE id=? JDBCRemoveEntityCommand.IdentityProperty] Remove: Rows affected = 1 JDBCRemoveEntityCommand.Identity] Checking if already deleted: id100169country JDBCRemoveEntityCommand.Identity] Deleteing: id100169country JDBCRemoveEntityCommand.IdentityProperty] Executing SQL: DELETE FROM ACS_IDENTITYPROPERTY WHERE id=? JDBCRemoveEntityCommand.IdentityProperty] Remove: Rows affected = 1 JDBCRemoveEntityCommand.Identity] Checking if already deleted: 4885910 JDBCRemoveEntityCommand.Identity] Deleteing: 4885910 JDBCLoadRelationCommand.Login] Executing SQL: SELECT id, name, value FROM ACS_LOGINPROPERTY WHERE (loginid=?) JDBCRemoveEntityCommand.Login] Executing SQL: DELETE FROM ACS_LOGIN WHERE loginid=? JDBCStoreEntityCommand.Login] Executing SQL: UPDATE ACS_LOGIN SET identityid=? WHERE loginid=? 2003-08-29 13:39:14,209 ERROR [org.jboss.ejb.plugins.LogInterceptor] TransactionRolledbackException, causedBy: javax.ejb.EJBException: Update failed. Expected one affected row: rowsAffected=0id=4885910 Looking at the last two statements, this is expected result. Does LoginProperties have sync-on-commit-only set also to true? Are all the beans have it as true? Because we're only using CMP2 for this set of related entities, I've been setting sync-on-commit-only=true globally in standardjboss.xml. This is also where I've been turing on/off call-logging. at org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreEntityCommand.execute(JDBCStoreEntityCommand.java:165) at org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager.storeEntity(JDBCStoreManager.java:649) at org.jboss.ejb.plugins.CMPPersistenceManager.storeEntity(CMPPersistenceManager.java:434) at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.storeEntity(CachedConnectionInterceptor.java:388) at org.jboss.ejb.EntityContainer.storeEntity(EntityContainer.java:702) at org.jboss.ejb.GlobalTxEntityMap.synchronizeEntities(GlobalTxEntityMap.java:163) at org.jboss.ejb.GlobalTxEntityMap$GlobalTxEntityMapCleanup.beforeCompletion(GlobalTxEntityMap.java:227) at org.jboss.tm.TransactionImpl.doBeforeCompletion(TransactionImpl.java:1297) at org.jboss.tm.TransactionImpl.commit(TransactionImpl.java:338) ... Oddly, if I turn on call logging there's also an exception thrown when deleting from t
Re: [JBoss-user] sync-on-commit-only and cascade-delete
Hello, Andrew. my comments in-lined. Andrew May wrote: I'm having a problem trying to user sync-on-commit-only and cascade-delete with JBoss 3.2.1 (Sun JDK1.4.2, Solaris). We've got a number of related entities like this: LOGIN---IDENTITY | | LOGINPROPERTIES IDENTITYPROPERTIES login->identity, login->loginproperties & identity->identityproperties are 1-M relationships and are defined as cascade-delete. To be exact: LOGIN - IDENTITY: M-1 IDENTITY - IDENTITYPROPERTIES: 1-M LOGIN - LOGINPROPERTIES: 1-M correct? When we originally developed the application on JBoss 3.0 there wasn't (or I wasn't aware of it) a sync-on-commit-only option, so all our foreign keys are nullable, and also our properties foreign keys (loginid and identityid) are not part of the primary key of the properties because I don't think this was possible at the time either. The entities are actually using views on an Oracle database. For various reasons we need to keep data that has been deleted, so when a delete is performed a hidden state is changed and the records no longer appear in the view but still exist in the table. We're now developing an API for maintaining the data (previously any deletes were done directly in the database) and we're having to think about how the EJB remove() calls interact with the database and the views and the triggers that maintain the views. If sync-on-commit-only=false then as per the spec all the relationships are broken before the entities are deleted. This looks OK to the application and in the views, but the data in the tables that's kept has had all the relationships broken and is no longer useful. With sync-on-commit-only=false things work fine in the simple cases: If I guess, I meant sync-on-commit-only=true, right? I delete a login, it is deleted as are it's properties (although I'm a bit surprised that the properties are deleted after the login). If I yes, it works that way. delete an identity that doesn't have any logins it works OK. However, if I delete an identity that has logins it fails: JDBCRemoveEntityCommand.Identity] Executing SQL: DELETE FROM ACS_IDENTITY WHERE identityid=? JDBCRemoveEntityCommand.Identity] Remove: Rows affected = 1 JDBCRemoveEntityCommand.Identity] Checking if already deleted: id100169city JDBCRemoveEntityCommand.Identity] Deleteing: id100169city JDBCRemoveEntityCommand.IdentityProperty] Executing SQL: DELETE FROM ACS_IDENTITYPROPERTY WHERE id=? JDBCRemoveEntityCommand.IdentityProperty] Remove: Rows affected = 1 JDBCRemoveEntityCommand.Identity] Checking if already deleted: id100169country JDBCRemoveEntityCommand.Identity] Deleteing: id100169country JDBCRemoveEntityCommand.IdentityProperty] Executing SQL: DELETE FROM ACS_IDENTITYPROPERTY WHERE id=? JDBCRemoveEntityCommand.IdentityProperty] Remove: Rows affected = 1 JDBCRemoveEntityCommand.Identity] Checking if already deleted: 4885910 JDBCRemoveEntityCommand.Identity] Deleteing: 4885910 JDBCLoadRelationCommand.Login] Executing SQL: SELECT id, name, value FROM ACS_LOGINPROPERTY WHERE (loginid=?) JDBCRemoveEntityCommand.Login] Executing SQL: DELETE FROM ACS_LOGIN WHERE loginid=? JDBCStoreEntityCommand.Login] Executing SQL: UPDATE ACS_LOGIN SET identityid=? WHERE loginid=? 2003-08-29 13:39:14,209 ERROR [org.jboss.ejb.plugins.LogInterceptor] TransactionRolledbackException, causedBy: javax.ejb.EJBException: Update failed. Expected one affected row: rowsAffected=0id=4885910 Looking at the last two statements, this is expected result. Does LoginProperties have sync-on-commit-only set also to true? Are all the beans have it as true? at org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreEntityCommand.execute(JDBCStoreEntityCommand.java:165) at org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager.storeEntity(JDBCStoreManager.java:649) at org.jboss.ejb.plugins.CMPPersistenceManager.storeEntity(CMPPersistenceManager.java:434) at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.storeEntity(CachedConnectionInterceptor.java:388) at org.jboss.ejb.EntityContainer.storeEntity(EntityContainer.java:702) at org.jboss.ejb.GlobalTxEntityMap.synchronizeEntities(GlobalTxEntityMap.java:163) at org.jboss.ejb.GlobalTxEntityMap$GlobalTxEntityMapCleanup.beforeCompletion(GlobalTxEntityMap.java:227) at org.jboss.tm.TransactionImpl.doBeforeCompletion(TransactionImpl.java:1297) at org.jboss.tm.TransactionImpl.commit(TransactionImpl.java:338) ... Oddly, if I turn on call logging there's also an exception thrown when deleting from the ACS_LOGIN table: JDBCRemoveEntityCommand.Identity] Checking if already deleted: id100169lastName JDBCRemoveEntityCommand.Identity] Deleteing: id100169lastName LogInterceptor] Invoke: [id100169lastName] remove() JDBCRemoveEntityCommand.IdentityProperty] Executing SQL: DELETE FROM ACS_IDENTITYPROPERTY WHERE id =? JDBCRemoveEntityCommand.IdentityPropert
[JBoss-user] sync-on-commit-only and cascade-delete
I'm having a problem trying to user sync-on-commit-only and cascade-delete with JBoss 3.2.1 (Sun JDK1.4.2, Solaris). We've got a number of related entities like this: LOGIN---IDENTITY | | LOGINPROPERTIES IDENTITYPROPERTIES login->identity, login->loginproperties & identity->identityproperties are 1-M relationships and are defined as cascade-delete. When we originally developed the application on JBoss 3.0 there wasn't (or I wasn't aware of it) a sync-on-commit-only option, so all our foreign keys are nullable, and also our properties foreign keys (loginid and identityid) are not part of the primary key of the properties because I don't think this was possible at the time either. The entities are actually using views on an Oracle database. For various reasons we need to keep data that has been deleted, so when a delete is performed a hidden state is changed and the records no longer appear in the view but still exist in the table. We're now developing an API for maintaining the data (previously any deletes were done directly in the database) and we're having to think about how the EJB remove() calls interact with the database and the views and the triggers that maintain the views. If sync-on-commit-only=false then as per the spec all the relationships are broken before the entities are deleted. This looks OK to the application and in the views, but the data in the tables that's kept has had all the relationships broken and is no longer useful. With sync-on-commit-only=false things work fine in the simple cases: If I delete a login, it is deleted as are it's properties (although I'm a bit surprised that the properties are deleted after the login). If I delete an identity that doesn't have any logins it works OK. However, if I delete an identity that has logins it fails: JDBCRemoveEntityCommand.Identity] Executing SQL: DELETE FROM ACS_IDENTITY WHERE identityid=? JDBCRemoveEntityCommand.Identity] Remove: Rows affected = 1 JDBCRemoveEntityCommand.Identity] Checking if already deleted: id100169city JDBCRemoveEntityCommand.Identity] Deleteing: id100169city JDBCRemoveEntityCommand.IdentityProperty] Executing SQL: DELETE FROM ACS_IDENTITYPROPERTY WHERE id=? JDBCRemoveEntityCommand.IdentityProperty] Remove: Rows affected = 1 JDBCRemoveEntityCommand.Identity] Checking if already deleted: id100169country JDBCRemoveEntityCommand.Identity] Deleteing: id100169country JDBCRemoveEntityCommand.IdentityProperty] Executing SQL: DELETE FROM ACS_IDENTITYPROPERTY WHERE id=? JDBCRemoveEntityCommand.IdentityProperty] Remove: Rows affected = 1 JDBCRemoveEntityCommand.Identity] Checking if already deleted: 4885910 JDBCRemoveEntityCommand.Identity] Deleteing: 4885910 JDBCLoadRelationCommand.Login] Executing SQL: SELECT id, name, value FROM ACS_LOGINPROPERTY WHERE (loginid=?) JDBCRemoveEntityCommand.Login] Executing SQL: DELETE FROM ACS_LOGIN WHERE loginid=? JDBCStoreEntityCommand.Login] Executing SQL: UPDATE ACS_LOGIN SET identityid=? WHERE loginid=? 2003-08-29 13:39:14,209 ERROR [org.jboss.ejb.plugins.LogInterceptor] TransactionRolledbackException, causedBy: javax.ejb.EJBException: Update failed. Expected one affected row: rowsAffected=0id=4885910 at org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreEntityCommand.execute(JDBCStoreEntityCommand.java:165) at org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager.storeEntity(JDBCStoreManager.java:649) at org.jboss.ejb.plugins.CMPPersistenceManager.storeEntity(CMPPersistenceManager.java:434) at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.storeEntity(CachedConnectionInterceptor.java:388) at org.jboss.ejb.EntityContainer.storeEntity(EntityContainer.java:702) at org.jboss.ejb.GlobalTxEntityMap.synchronizeEntities(GlobalTxEntityMap.java:163) at org.jboss.ejb.GlobalTxEntityMap$GlobalTxEntityMapCleanup.beforeCompletion(GlobalTxEntityMap.java:227) at org.jboss.tm.TransactionImpl.doBeforeCompletion(TransactionImpl.java:1297) at org.jboss.tm.TransactionImpl.commit(TransactionImpl.java:338) ... Oddly, if I turn on call logging there's also an exception thrown when deleting from the ACS_LOGIN table: JDBCRemoveEntityCommand.Identity] Checking if already deleted: id100169lastName JDBCRemoveEntityCommand.Identity] Deleteing: id100169lastName LogInterceptor] Invoke: [id100169lastName] remove() JDBCRemoveEntityCommand.IdentityProperty] Executing SQL: DELETE FROM ACS_IDENTITYPROPERTY WHERE id =? JDBCRemoveEntityCommand.IdentityProperty] Remove: Rows affected = 1 JDBCRemoveEntityCommand.Identity] Checking if already deleted: 4885910 JDBCRemoveEntityCommand.Identity] Deleteing: 4885910 LogInterceptor] Invoke: [4885910] remove() LogInterceptor] Invoke: [4885910hidden] ([EMAIL PROTECTED],4885910) JDBCRemoveEntityCommand.Login] Executing SQL: DELETE FROM ACS_LOGIN WHERE loginid=? LogInterceptor] Application Exception javax.ejb.RemoveException: Could not remove