When attempting to remove a bean that has cascading deletion defined on its 
relationship to another bean, I sometimes receive an NPE when the removal is 
attempted. The relevant portion of the stack trace is as follows:


  | 14:03:34,448 INFO  [STDOUT] 
com.gg.security.permissions.exception.PermissionsException: Could not delete 
old permissions for [FolderContainedEntityEJB: path='testperm/test1', 
parentPath='testperm', id='7fbc44610a0001ee01cb95b31eb23fd7']: Could not delete 
entity: null
  | 14:03:34,449 INFO  [STDOUT]     at 
com.gg.model.security.permissions.modify.PermissionsModifierImpl.deletePermissions(PermissionsModifierImpl.java:237)
  | 14:03:34,449 INFO  [STDOUT]     at 
com.gg.model.security.permissions.modify.PermissionsModifierImpl.ensurePermissions(PermissionsModifierImpl.java:216)
  | 14:03:34,449 INFO  [STDOUT]     at 
com.gg.model.security.permissions.modify.PermissionsModifierImpl.modify(PermissionsModifierImpl.java:70)
  | ...
  | 14:03:34,460 INFO  [STDOUT] Caused by: java.lang.NullPointerException
  | 14:03:34,460 INFO  [STDOUT]     at 
org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager$CascadeDeleteRegistry.unschedule(JDBCStoreManager.java:752)
  | 14:03:34,460 INFO  [STDOUT]     at 
org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager.unscheduledCascadeDelete(JDBCStoreManager.java:259)
  | 14:03:34,460 INFO  [STDOUT]     at 
org.jboss.ejb.plugins.cmp.jdbc.CascadeDeleteStrategy$BatchCascadeDeleteStrategy.cascadeDelete(CascadeDeleteStrategy.java:168)
  | 14:03:34,461 INFO  [STDOUT]     at 
org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMRFieldBridge.cascadeDelete(JDBCCMRFieldBridge.java:406)
  | 14:03:34,461 INFO  [STDOUT]     at 
org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCEntityBridge.cascadeDelete(JDBCEntityBridge.java:322)
  | 14:03:34,461 INFO  [STDOUT]     at 
org.jboss.ejb.plugins.cmp.jdbc.JDBCRemoveEntityCommand.execute(JDBCRemoveEntityCommand.java:117)
  | 14:03:34,461 INFO  [STDOUT]     at 
org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager.removeEntity(JDBCStoreManager.java:682)
  | 14:03:34,461 INFO  [STDOUT]     at 
org.jboss.ejb.plugins.CMPPersistenceManager.removeEntity(CMPPersistenceManager.java:466)
  | 14:03:34,461 INFO  [STDOUT]     at 
org.jboss.resource.connectionmanager.CachedConnectionInterceptor.removeEntity(CachedConnectionInterceptor.java:457)
  | 14:03:34,461 INFO  [STDOUT]     at 
org.jboss.ejb.EntityContainer.remove(EntityContainer.java:500)
  | 14:03:34,461 INFO  [STDOUT]     at 
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  | 14:03:34,461 INFO  [STDOUT]     at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
  | 14:03:34,461 INFO  [STDOUT]     at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  | 14:03:34,461 INFO  [STDOUT]     at 
java.lang.reflect.Method.invoke(Method.java:585)
  | 14:03:34,461 INFO  [STDOUT]     at 
org.jboss.ejb.EntityContainer$ContainerInterceptor.invoke(EntityContainer.java:1107)
  | 14:03:34,461 INFO  [STDOUT]     at 
org.jboss.ejb.plugins.cmp.jdbc.JDBCRelationInterceptor.invoke(JDBCRelationInterceptor.java:72)
  | 14:03:34,461 INFO  [STDOUT]     at 
org.jboss.ejb.plugins.EntitySynchronizationInterceptor.invoke(EntitySynchronizationInterceptor.java:345)
  | 14:03:34,461 INFO  [STDOUT]     at 
org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:186)
  | 14:03:34,462 INFO  [STDOUT]     at 
org.jboss.ejb.plugins.EntityReentranceInterceptor.invoke(EntityReentranceInterceptor.java:116)
  | 14:03:34,462 INFO  [STDOUT]     at 
org.jboss.ejb.plugins.EntityInstanceInterceptor.invoke(EntityInstanceInterceptor.java:211)
  | 14:03:34,462 INFO  [STDOUT]     at 
org.jboss.ejb.plugins.EntityLockInterceptor.invoke(EntityLockInterceptor.java:89)
  | 14:03:34,462 INFO  [STDOUT]     at 
org.jboss.ejb.plugins.EntityCreationInterceptor.invoke(EntityCreationInterceptor.java:54)
  | 14:03:34,462 INFO  [STDOUT]     at 
org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:84)
  | 14:03:34,462 INFO  [STDOUT]     at 
org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:343)
  | 14:03:34,462 INFO  [STDOUT]     at 
org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:150)
  | 14:03:34,462 INFO  [STDOUT]     at 
org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:111)
  | 14:03:34,462 INFO  [STDOUT]     at 
org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:122)
  | 14:03:34,462 INFO  [STDOUT]     at 
org.jboss.ejb.EntityContainer.internalInvoke(EntityContainer.java:484)
  | 14:03:34,462 INFO  [STDOUT]     at 
org.jboss.ejb.Container.invoke(Container.java:709)
  | 14:03:34,472 INFO  [STDOUT]     at 
org.jboss.ejb.plugins.local.BaseLocalProxyFactory.invoke(BaseLocalProxyFactory.java:419)
  | 14:03:34,472 INFO  [STDOUT]     at 
org.jboss.ejb.plugins.local.EntityProxy.invoke(EntityProxy.java:44)
  | 14:03:34,472 INFO  [STDOUT]     at $Proxy271.remove(Unknown Source)
  | 14:03:34,472 INFO  [STDOUT]     at 
com.gg.adapter.BaseEntityAdapter.remove(BaseEntityAdapter.java:90)
  | 14:03:34,473 INFO  [STDOUT]     at 
com.gg.model.delete.BaseEntityDeleter.delete(BaseEntityDeleter.java:24)
  | 14:03:34,473 INFO  [STDOUT]     at 
com.gg.manager.remove.EntityRemoverImpl.removeEntity(EntityRemoverImpl.java:35)
  | 14:03:34,473 INFO  [STDOUT]     ... 66 more
  | 

The basic scenario is that a folder in the app has some permissions, which in 
turn are defined by a number of "access control list entries" (aka ACLEntries). 
 Thus, a one-to-many CMR relationship between the Permissions and ACLEntry 
beans, which is defined like so:

PermissionsBean.java

  | /**
  |  * @ejb.bean             
  |  *          name="Permissions" 
  |  *          type="CMP" 
  |  *          view-type="local" 
  |  *          local-jndi-name="ejb/Permissions"
  |  *      reentrant="false" 
  |  *          primkey-field="id"
  |  *          schema="Permissions"
  |  *          transaction-type="Container"
  |  *          cmp-version="2.x"
  |  * 
  |  * @ejb.interface           
  |  *          
local-class="com.gg.model.security.permissions.interfaces.Permissions" 
  |  *          local-extends="com.hannonhill.object.interfaces.BaseEntity"
  |  * @ejb.home                
  |  *          
local-class="com.gg.model.security.permissions.interfaces.PermissionsHome" 
  |  *          local-extends="javax.ejb.EJBLocalHome"
  |  * 
  |  * @ejb.pk                  
  |  *          class="java.lang.String" extends="java.lang.Object"
  |  * 
  |  * @jboss.persistence        
  |  *          create-table="true"
  |  * 
  |  * @ejb.persistence         
  |  *          table-name="permissions"
  |  * 
  |  * @ejb.util
  |  *          generate="physical"
  |  * 
  |  * @jboss.container-configuration
  |  *          name="CMP 2.x and Cache"
  |  * 
  |  * @ejb.transaction
  |  *          type="Supports"
  |  *  
  |  */
  | public abstract class PermissionsBean extends BaseEntityBean implements 
PermissionsLevels 
  | {
  |     <!-- some unrelated ejb code -->
  |     
  |     /**
  |      * Returns a collection of ACLEntries this Permissions object contains.
  |      *
  |      * @ejb.relation            
  |      *      name="aclentry-has-permissions" 
  |      *      role-name="permission-aclentrys"
  |      *      target-ejb="ACLEntry"
  |      * @ejb.interface-method 
  |      *      view-type="local"
  |      * 
  |      * @jboss.method-attributes
  |      *      read-only="true"
  |      */
  |     public abstract java.util.Collection getACLEntries();
  | 
  |     /**
  |      * sets the Collection of Destination objects for this Target.
  |      * 
  |      * @ejb.interface-method 
  |      *      view-type="local"
  |      * @ejb.transaction 
  |      *      type="Required"
  |      */
  |     public abstract void setACLEntries(java.util.Collection aclEntries);
  | 
  |     /**
  |      * Deletes this entity.
  |      */
  |     public void ejbRemove() throws RemoveException
  |     {
  |         super.ejbRemove();
  |     }    
  | 
  |     <!-- more unrelated ejb stuff -->
  | }
  | 

ACLEntryBean.java

  | /**
  |  * @ejb.bean             
  |  *      name="ACLEntry" 
  |  *      type="CMP" 
  |  *      view-type="local" 
  |  *      local-jndi-name="ejb/ACLEntry"
  |  *      reentrant="false" 
  |  *      primkey-field="id"
  |  *      schema="ACLEntry"
  |  *      transaction-type="Container"
  |  *      cmp-version="2.x"
  |  * 
  |  * @ejb.interface           
  |  *      local-class="com.gg.model.security.permissions.interfaces.ACLEntry" 
  |  *      local-extends="com.hannonhill.object.interfaces.BaseEntity"
  |  * @ejb.home                
  |  *      local-class="com.gg.security.permissions.interfaces.ACLEntryHome" 
  |  *      local-extends="javax.ejb.EJBLocalHome"
  |  * 
  |  * @ejb.pk                  
  |  *      class="java.lang.String" extends="java.lang.Object"
  |  * 
  |  * @jboss.persistence        
  |  *      create-table="true"
  |  * 
  |  * @ejb.persistence         
  |  *      table-name="aclentry"
  |  * 
  |  * @ejb.util
  |  *      generate="physical"
  |  * 
  |  * @jboss.container-configuration
  |  *      name="CMP 2.x and Cache"
  |  * 
  |  * @ejb.transaction
  |  *      type="Supports"
  |  *      
  |  * @ejb.finder
  |  *      signature="com.gg.security.permissions.interfaces.ACLEntry 
findByPrimaryKey(java.lang.String pk)"
  |  *      query="SELECT OBJECT(x) FROM ACLEntry AS x WHERE x.id = ?1"
  |  */
  | public abstract class ACLEntryBean extends BaseEntityBean
  | {
  |     <!-- some unrelated ejb stuff -->
  |     
  |     /**
  |      * @ejb.relation            
  |      *      name="aclentry-has-permissions" 
  |      *      role-name="aclentry-permissions"
  |      *      target-ejb="Permissions"
  |      *      cascade-delete="yes"
  |      * @jboss.relation          
  |      *      related-pk-field="id" 
  |      *      fk-column="permissionsId"
  |      *      batch-cascade-delete="true"
  |      *      
  |      * @ejb.interface-method 
  |      *      view-type="local"
  |      * 
  |      * @jboss.method-attributes
  |      *      read-only="true"
  |      */
  |     public abstract com.gg.security.permissions.intefaces.Permissions 
getPermissions();
  | 
  |     /**
  |      * @ejb.interface-method 
  |      *      view-type="local"
  |      * @ejb.transaction 
  |      *      type="Required"
  |      */
  |     public abstract void setPermissions(Permissions permissions);
  |     
  |     /**
  |      * Vanilla ejb remove.
  |      */
  |     public void ejbRemove() throws RemoveException
  |     {
  |         super.ejbRemove();
  |     }    
  | 
  |     <!-- more ejb junk here -->
  | }
  | 

The deletion of these beans is accomplished through calling 
PermissionsModifierImpl.deletePermissions(...), which you see in the stack 
trace above.

PermissionsModifierImpl.java

  |     /**
  |      * Deletes the permissions object associated with this entity.
  |      * @param entity
  |      */
  |     private void deletePermissions(PermissionsCapable entity) throws 
PermissionsException
  |     {
  |         EntityRemover remover = 
getEntityManagerFactory().getManager().getRemover();
  |         MutablePermissions permissions = entity.getPermissions();
  |         if (permissions != null)
  |         {
  |             try
  |             {
  |                 remover.removeEntity(entity.getPermissions());
  |                 entity.setPermissions(null);
  |             }
  |             catch (Exception e)
  |             {
  |                 throw new PermissionsException("Could not delete old 
permissions for " + entity + ": " + e.getMessage(), e);
  |             }
  |         }
  |     }
  | 

Curiously, a failed deletion leaves the child folder bean in a state where its 
permissions are null, and attempting the modification again will result in 
success. If the permissions are set on the child folder bean after the failed 
modification, however, the subsequent modification will also fail.

We are using similar cascading deletion in other places in our application with 
no problems. Any ideas as to why this might be happening?

View the original post : 
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4031747#4031747

Reply to the post : 
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4031747
_______________________________________________
jboss-user mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/jboss-user

Reply via email to