10 Replies Latest reply on Apr 19, 2004 3:34 PM by davout

    How to delete child entities only from a one-to-many CMR rel

    davout

      Can somebody explain with a code example how to delete all the child entities of a CMR one-to-many relationship without deleting the parent?

      For example: a 'Pupil' entity is associated with one or more 'subject' entities. I have a 'Pupil' entity bean, 'Subject' entity bean and a linking 'PupilSubjectLink' entity bean. This last bean has two fields 'PupilID' and 'SubjectID', both set as keys. I have a CMR one-to-many relationship set up from the 'Pupil' entity to the 'PupilSubjectLink' entity - called 'subjectLinks'.

      Here's my code, from a facade session bean ...

      Pupil aPupil = getHome().findByPrimaryKey(...)
      Collection aSubjectLinks = aPupil.getSubjectLinks;
      Iterator anIterator = aSubjectLinks.iterator();
      while (anIterator.hasNext()) {
       PupilSubjectLink aLink = (PupilSubjectLink) anIterator.next();
       aSubjectLinks.remove(aLink);
      }
      


      This doesn't work. I've even tried setting the session bean method to use a 'RequiresNew' transaction state.

      Previously I tried calling 'aLink.remove()' within the while loop but this caused problems with subsequent use of 'aPupil.getSubjectLinks'.

      Any ideas?





        • 1. Re: How to delete child entities only from a one-to-many CMR
          triathlon98

          Chnage your code to

          Pupil aPupil = getHome().findByPrimaryKey(...)
          Collection aSubjectLinks = aPupil.getSubjectLinks;
          Iterator anIterator;
          while ((anIterator = aSubjectLinks.iterator()).hasNext()) {
           PupilSubjectLink aLink = (PupilSubjectLink) anIterator.next();
           aSubjectLinks.remove(aLink);
          }
          


          Once you remove something from an iterator, it is invalidated, so you have to start with a new iterator.

          Joachim

          • 2. Re: How to delete child entities only from a one-to-many CMR
            davout

            Thanks for the code pointer...

            Unfortunately the records are not being deleted from the MySQL table. After I run the code and use a DB tool to view the table data the records are still there.

            I checked the EJB code by having 'System.out' messages display the before and after state of the collection - the collection is empty at tyhre end of the method

            Any ideas??

            • 3. Re: How to delete child entities only from a one-to-many CMR
              davout

              Some more info...

              After running the delete method call the first time my System.out messages show a collection size of '2' at the start and '0' at the finish.

              If I run the same delete method call a second time the collection size is'2' - so obviously something isn't executing the first time round.

              • 4. Re: How to delete child entities only from a one-to-many CMR
                triathlon98

                Switch on debugging for the CMP stuff. This should show whether the delete SQL queries are being generated.

                You are sure your transaction has finished and is not rolled back?

                Joachim

                • 5. Re: How to delete child entities only from a one-to-many CMR
                  sesques

                  It seems curious that you do not have any error !
                  How your beans are defined (post the ejb-jar and jbosscmp-jdbc files).
                  Are you sure the database you look at is the one used by JBoss ? (Does JBoss create the tables ?)

                  • 6. Re: How to delete child entities only from a one-to-many CMR
                    davout

                    How do you switch on debugging for the CMP stuff?

                    • 7. Re: How to delete child entities only from a one-to-many CMR
                      sesques

                      Adds

                      <category name="org.jboss.ejb.plugins">
                       <priority value="TRACE" class="org.jboss.logging.XLevel"/>
                      </category>
                      


                      in the log4j.xml file (in the conf directory)


                      • 8. Re: How to delete child entities only from a one-to-many CMR
                        davout

                        This is the log output created by one of the '.remove(aLink)' calls. The [STDOUT] lines are the before and after System.out lines insertd by me within the method code.

                        2004-04-19 20:07:34,943 INFO [STDOUT] Deleting [4/3]
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor] invokerBInding is null in ProxyFactoryFinder
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.LogInterceptor] Start method=getPlatformLinks
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.TxInterceptorCMT] Current transaction in MI is TransactionImpl:XidImpl [FormatId=257, GlobalId=dell55//37, BranchQual=]
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.TxInterceptorCMT] TX_REQUIRED for getPlatformLinks
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.TxInterceptorCMT] Thread came in with tx TransactionImpl:XidImpl [FormatId=257, GlobalId=dell55//37, BranchQual=]
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.EntityLockInterceptor] Begin invoke, key=4
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.EntityInstanceInterceptor] Begin invoke, key=4
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.EntitySynchronizationInterceptor] invoke called for ctx org.jboss.ejb.EntityEnterpriseContext@cac02f, tx=TransactionImpl:XidImpl [FormatId=257, GlobalId=dell55//37, BranchQual=]
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.EntitySynchronizationInterceptor] register, ctx=org.jboss.ejb.EntityEnterpriseContext@cac02f, tx=TransactionImpl:XidImpl [FormatId=257, GlobalId=dell55//37, BranchQual=]
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.EntitySynchronizationInterceptor] register, ctx=org.jboss.ejb.EntityEnterpriseContext@cac02f, tx=TransactionImpl:XidImpl [FormatId=257, GlobalId=dell55//37, BranchQual=]
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.EntityInstanceInterceptor] End invoke, key=4, ctx=org.jboss.ejb.EntityEnterpriseContext@cac02f
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.EntityLockInterceptor] End invoke, key=4
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.TxInterceptorCMT] TxInterceptorCMT: In finally
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.LogInterceptor] End method=getPlatformLinks
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor] invokerBInding is null in ProxyFactoryFinder
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.LogInterceptor] Start method=<no method>
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.TxInterceptorCMT] Current transaction in MI is TransactionImpl:XidImpl [FormatId=257, GlobalId=dell55//37, BranchQual=]
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.TxInterceptorCMT] TX_SUPPORTS for <no method>
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.TxInterceptorCMT] Thread came in with tx TransactionImpl:XidImpl [FormatId=257, GlobalId=dell55//37, BranchQual=]
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.EntityLockInterceptor] Begin invoke, key=9
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.EntityInstanceInterceptor] Begin invoke, key=9
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.EntityReentranceInterceptor] NON_ENTRANT invocation
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.EntitySynchronizationInterceptor] invoke called for ctx org.jboss.ejb.EntityEnterpriseContext@ed3bff, tx=TransactionImpl:XidImpl [FormatId=257, GlobalId=dell55//37, BranchQual=]
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.EntitySynchronizationInterceptor] register, ctx=org.jboss.ejb.EntityEnterpriseContext@ed3bff, tx=TransactionImpl:XidImpl [FormatId=257, GlobalId=dell55//37, BranchQual=]
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.cmp.jdbc.JDBCRelationInterceptor.OpSysPlatformLink] Remove relation: field=OpSys_platformLinks id=9 relatedId=4
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.EntitySynchronizationInterceptor] register, ctx=org.jboss.ejb.EntityEnterpriseContext@ed3bff, tx=TransactionImpl:XidImpl [FormatId=257, GlobalId=dell55//37, BranchQual=]
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.EntityInstanceInterceptor] End invoke, key=9, ctx=org.jboss.ejb.EntityEnterpriseContext@ed3bff
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.EntityLockInterceptor] End invoke, key=9
                        
                        2004-04-19 20:07:34,943 TRACE [org.jboss.ejb.plugins.LogInterceptor] End method=<no method>
                        
                        2004-04-19 20:07:34,943 INFO [STDOUT] ... deleted
                        
                        


                        Any ideas?



                        • 9. Re: How to delete child entities only from a one-to-many CMR
                          sesques

                          We are all silly !
                          In your code, you only remove the entity bean from the collection, not the bean itself.

                          Try this code:

                          Pupil aPupil = getHome().findByPrimaryKey(...)
                          Collection aSubjectLinks = aPupil.getSubjectLinks;
                          Iterator anIterator;
                          while (aSubjectLinks.size() != 0) {
                           PupilSubjectLink aLink = (PupilSubjectLink) aSubjectLinks.iterator().next();
                           aSubjectLinks.remove(aLink);
                           aLink.remove();
                           // aSubjectLinks.clear() if needed
                           aSubjectLinks = aPupil.getSubjectLinks;
                          }
                          


                          The solution is in this way...




                          • 10. Re: How to delete child entities only from a one-to-many CMR
                            davout

                            That's solved it! Many thanks.