2 Replies Latest reply: Nov 16, 2012 2:08 AM by Cvele_new_account RSS

    Retain uncommited ViewObject Row on App Module Rollback

    Cvele_new_account
      Hi all,

      In my app module, I have two (entity based) instances of the same VO.
      One of them have the "no rows has to be fetched" setting (so, used only for inserting new rows).
      Also, for another instance, I disabled View link consistency, by using
          setAssociationConsistent(false);
      At begging of TF, I created one new Row for that ("no fetch rows") instance, and, in order to preserve that Row on app module Rollback, follow instruction at:

      https://blogs.oracle.com/vijaymohan/entry/clearcache_entity_based_view_object_and_transient_view_object_scenario


      So, for that VO instance, I override afterRollback() and beforeRollback() (commented out super call).
      But after rollback, the new uncommited Row disappears.

      Any idea how to preserve uncommited row on App module rollback ?

      P.S. JDev 11.1.1.6

      Edited by: Cvele_new_account on Nov 15, 2012 4:32 AM
        • 1. Re: Retain uncommited ViewObject Row on App Module Rollback
          Frank Nimphius-Oracle
          Hi,

          I think you will have to save away the rows - outside of the entity cache - and then re-create them after roll back

          Frank
          • 2. Re: Retain uncommited ViewObject Row on App Module Rollback
            Cvele_new_account
            Hi Frank,
            Thanks for response

            That's what I basically did, but must take into account some other things.
            Here is details:

            In the ViewObjectImpl:
                NameValuePairs nv = null;
                 /**
                  * For VO instance ("NoRows_VOInstance") with uncommited Row, which must survive Rollback, remember NameValuePairs, i norder to re-create and insert Row after rollback:
                 */ 
                public void beforeRollback(TransactionEvent e){
                    if ("NoRows_VOInstance".equalsIgnoreCase(getName())) {
                       if (getCurrentRow() != null) {
                           nv = new NameValuePairs(getCurrentRow().getAttributeNames(), getCurrentRow().getAttributeValues());
                       }    
                    }else{
                       super.beforeRollback(e);                
                    }
                }
                   /**
                   * If there is  remembered NameValuePairs, re-create and insert Row
                   */
                   public void afterRollback(TransactionEvent event){
                    if ("NoRows_VOInstance".equalsIgnoreCase(getName())) {
                       if (this.getRowCount() == 0 && nv != null) {
                           insertRow(createAndInitRow(nv));
                           nv = null;
                       } 
                    }else{
                       super.afterRollback(event);                
                    }
                }
            But this is not enough, because of after that, as a result of rollback call, the framework calls ApplicationModuleImpl.clearVOCaches(). This method :
            Clears the caches of all View Objects that use the specified entity. This method finds all View Objects that use the entity, then calls
            oracle.jbo.ViewObject#clearCache() on each View Object.
            So in order for re-created row to survive, it is necessary to avoid clearing VO instance cache.
            To find objects that are used specified entity, framework calls
                public void findVOsWithEntityUsage(String entityName, boolean recurse, java.util.Vector vos)
            Third (output) param,*vos*, is a Vector of View Objects whose cache should be cleaned.
            So I override findVOsWithEntityUsage() so that after the super call, I simply remove my VO instance

                public void findVOsWithEntityUsage(String entityName, boolean recurse, java.util.Vector vos) {
                    super.findVOsWithEntityUsage(entityName, recurse, vos);
                    Iterator it = vos.iterator();
                    while (it.hasNext()) {
                        ViewObjectImpl vo = (ViewObjectImpl)it.next();
                        if ("NoRows_VOInstance".equalsIgnoreCase(vo.getName()) &&
                            "mypackage.MyEntity".equalsIgnoreCase(entityName)) {
                             vos.remove(vo); // <-- here I simply remove my VO instance from the list
                             break;
                        }        
                    }
             
                }
            And voila, my uncommited row survives rollback ;-)