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] <no method>([EMAIL PROTECTED],4885910)
JDBCRemoveEntityCommand.Login] Executing SQL: DELETE FROM ACS_LOGIN WHERE loginid=?
LogInterceptor] Application Exception
javax.ejb.RemoveException: Could not remove entity
at org.jboss.ejb.plugins.cmp.jdbc.JDBCRemoveEntityCommand.execute(JDBCRemoveEntityCommand.java:108)
at org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager.removeEntity(JDBCStoreManager.java:695)
at org.jboss.ejb.plugins.CMPPersistenceManager.removeEntity(CMPPersistenceManager.java:518)
at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.removeEntity(CachedConnectionInterceptor.java:431)
at org.jboss.ejb.EntityContainer.remove(EntityContainer.java:497)
at sun.reflect.GeneratedMethodAccessor49.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at org.jboss.ejb.EntityContainer$ContainerInterceptor.invoke(EntityContainer.java:1032)
at org.jboss.ejb.plugins.cmp.jdbc.JDBCRelationInterceptor.invoke(JDBCRelationInterceptor.java:95)
at org.jboss.ejb.plugins.EntitySynchronizationInterceptor.invoke(EntitySynchronizationInterceptor.java:301)
at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:186)
at org.jboss.ejb.plugins.EntityReentranceInterceptor.invoke(EntityReentranceInterceptor.java:82)
at org.jboss.ejb.plugins.EntityInstanceInterceptor.invoke(EntityInstanceInterceptor.java:174)
at org.jboss.ejb.plugins.EntityLockInterceptor.invoke(EntityLockInterceptor.java:89)
at org.jboss.ejb.plugins.EntityCreationInterceptor.invoke(EntityCreationInterceptor.java:53)
at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:84)
at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:243)
at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:104)
at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:117)
at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:191)
at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:122)
at org.jboss.ejb.EntityContainer.internalInvoke(EntityContainer.java:483)
at org.jboss.ejb.Container.invoke(Container.java:674)
at org.jboss.ejb.plugins.local.BaseLocalProxyFactory.invoke(BaseLocalProxyFactory.java:353)
at org.jboss.ejb.plugins.local.EntityProxy.invoke(EntityProxy.java:38)
at $Proxy263.remove(Unknown Source)
at org.jboss.ejb.plugins.cmp.jdbc.JDBCRemoveEntityCommand.cascadeDelete(JDBCRemoveEntityCommand.java:188)
at org.jboss.ejb.plugins.cmp.jdbc.JDBCRemoveEntityCommand.execute(JDBCRemoveEntityCommand.java:113)
at org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager.removeEntity(JDBCStoreManager.java:695)
at org.jboss.ejb.plugins.CMPPersistenceManager.removeEntity(CMPPersistenceManager.java:518)
at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.removeEntity(CachedConnectionInterceptor.java:431)
at org.jboss.ejb.EntityContainer.remove(EntityContainer.java:497)
at sun.reflect.GeneratedMethodAccessor49.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at org.jboss.ejb.EntityContainer$ContainerInterceptor.invoke(EntityContainer.java:1032)
at org.jboss.ejb.plugins.cmp.jdbc.JDBCRelationInterceptor.invoke(JDBCRelationInterceptor.java:95)
at org.jboss.ejb.plugins.EntitySynchronizationInterceptor.invoke(EntitySynchronizationInterceptor.java:301)
at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:186)
at org.jboss.ejb.plugins.EntityReentranceInterceptor.invoke(EntityReentranceInterceptor.java:82)
at org.jboss.ejb.plugins.EntityInstanceInterceptor.invoke(EntityInstanceInterceptor.java:174)
at org.jboss.ejb.plugins.EntityLockInterceptor.invoke(EntityLockInterceptor.java:89)
at org.jboss.ejb.plugins.EntityCreationInterceptor.invoke(EntityCreationInterceptor.java:53)
at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:84)
at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:243)
at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:104)
at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:117)
at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:191)
at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:122)
at org.jboss.ejb.EntityContainer.internalInvoke(EntityContainer.java:483)
at org.jboss.ejb.Container.invoke(Container.java:674)
at org.jboss.ejb.plugins.local.BaseLocalProxyFactory.invoke(BaseLocalProxyFactory.java:353)
at org.jboss.ejb.plugins.local.EntityProxy.invoke(EntityProxy.java:38)
at $Proxy264.remove(Unknown Source)
and then goes on to throw the same UPDATE error as it does without call logging.
Anyone got any ideas?
Thanks,
Andrew
------------------------------------------------------- This sf.net email is sponsored by:ThinkGeek Welcome to geek heaven. http://thinkgeek.com/sf _______________________________________________ JBoss-user mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/jboss-user