2 Replies Latest reply on Dec 20, 2004 11:28 AM by Jonathon Roberts

    IllegalStateException when trying to remove CMR

    Sathya Sekar Newbie

      Hi,

      I have a simple customer-address CMR beans. User has an option to delete all the addresses for the customer in one click ! "How easy!" I thought and put in the below code :

      Collection allAddresses = getAddresses();
      Iterator iterator = allAddresses.iterator();
      
      while(iterator.hasNext()) {
       AddressLocal oldObj = (AddressLocal) iterator.next();
       oldObj.remove();
      }
      


      But when I tested, I immediately got the error :

      2004-09-09 09:44:40,655 ERROR [org.jboss.ejb.plugins.LogInterceptor] RuntimeException:
      java.lang.IllegalStateException: Underlying collection has been modified
       at org.jboss.ejb.plugins.cmp.jdbc.bridge.RelationSet$1.next(RelationSet.java:389)
       at com.mytest.ist.ejb.CustomerBean.removeAllAddresses(CustomerBean.java:396)
       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:324)
       at org.jboss.ejb.EntityContainer$ContainerInterceptor.invoke(EntityContainer.java:1114)
       at org.jboss.ejb.plugins.cmp.jdbc.JDBCRelationInterceptor.invoke(JDBCRelationInterceptor.java:72)
       at org.jboss.ejb.plugins.EntitySynchronizationInterceptor.invoke(EntitySynchronizationInterceptor.java:317)
       at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:185)
       at org.jboss.ejb.plugins.EntityReentranceInterceptor.invoke(EntityReentranceInterceptor.java:118)
       at org.jboss.ejb.plugins.EntityInstanceInterceptor.invoke(EntityInstanceInterceptor.java:175)
       at org.jboss.ejb.plugins.EntityLockInterceptor.invoke(EntityLockInterceptor.java:89)
       at org.jboss.ejb.plugins.EntityCreationInterceptor.invoke(EntityCreationInterceptor.java:54)
      


      I can see that there is some locking problem somewhere. But these are purely CMP beans. Any inputs on this ?

      TIA !

        • 1. Re: IllegalStateException when trying to remove CMR
          Sathya Sekar Newbie

          Answering my own post.

          The issue is that when a remove() command is issued on a bean, the container proceeds to delete the database record and also update the CMR field object - Collection or Set. So the iterator becomes invalid because the state of Collection object through which it is iterating has changed. I dont know whether there is any recommended solution to this - but the easiest workaround I put in was to save the references to the related bean objects in another Collection and iterate through that.

          Thus :

           Collection allAddresses = getAddresses();
          
           Iterator iterator = allAddresses.iterator();
           Vector tmp = new Vector();
          
           while(iterator.hasNext()) {
           AddressLocal oldObj = (AddressLocal) iterator.next();
           tmp.add(oldObj);
           }
          
           for(Enumeration e = tmp.elements();e.hasMoreElements();) {
           AddressLocal oldObj = (AddressLocal) e.nextElement();
           oldObj.remove();
           }
          


          This resolved the problem and the deletion went through fine !

          Any other clear approaches ?

          Thanks,.

          • 2. Re: IllegalStateException when trying to remove CMR
            Jonathon Roberts Newbie

            just call iterator.remove() right before you call the remove() on the bean.