This discussion is archived
2 Replies Latest reply: Nov 16, 2012 12:08 AM by Cvele_new_account RSS

Retain uncommited ViewObject Row on App Module Rollback

Cvele_new_account Expert
Currently Being Moderated
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 Employee ACE
    Currently Being Moderated
    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 Expert
    Currently Being Moderated
    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 ;-)

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points