Please disable your adblock and script blockers to view this page

Search this blog

Wednesday 2 April 2014

Performing Partial Rollback (Undo Changes) operation in ADF, Stay on current row after rollback

Hello All ,
This post talks about a common requirement of using partial rollback in ADF

Suppose there is two tables on page Departments and Employees, and i have changed one row in Departments table and same time created a row in Employees table, now i want to rollback the changes done in Departments table only

In this case if i use default Rollback operation then it will not only undo the changes of Department table but also remove the newly created row of Employees table
but this was not my purpose.

So to do this kind of things we can use partial rollback operation
  • I have created a fusion web application (Model & VC) using Departments & Employees Table of Oracle's default HR Schema

  • Now drop departments & employees VO on page with it's default operations (CreateInsert, Delete, Execute, Commit & Rollback) and a button to execute partial rollback of departments ViewObject


  • Here in this example i am creating partial rollback for Departments VO only, so to do this add a new transient attribute in Departments Vo to get current state of each row




  • How to get state of each row , in RowImpl class of departments ViewObject , write this code in getter of transient attribute or see my previous blog-post Identifying Modified/newely added row in af:table, get all modified rows of viewobject in bean

  •     /**
         * Gets the attribute value for the calculated attribute RowStatusTrans.
         * @return the RowStatusTrans
         */
        public Integer getRowStatusTrans() {
            /*here row is reference variable of collection, this expression returns an int value if it is
             2-Modified
             0-New
             1-Unmodified
            -1-Initialized
            */
            byte entityState = this.getEntity(0).getEntityState();
            return new Integer(entityState);
        }
    

  • Have created a method to remove newly added row , and to undo changes in existing rows of departments VO in Impl class

  •     /**Method to revert changes of current row
         * @param curRow
         */
        public void revertChangesCurrentRow(Row curRow) {
            if (curRow != null) {
                curRow.refresh(Row.REFRESH_UNDO_CHANGES | Row.REFRESH_WITH_DB_FORGET_CHANGES);
            }
        }
    
        /**Method to check whether row should be removed or not 
         * If it is new - removed
         * If old one- Undo Changes
         * */
        public void revertOrremoveRowValues() {
            ViewObject deptVo = this;
            RowSetIterator deptIter = deptVo.createRowSetIterator(null);
            while (deptIter.hasNext()) {
                Row nextRow = deptIter.next();
                if (nextRow.getAttribute("RowStatusTrans") != null) {
                    Integer rowStatus = (Integer) nextRow.getAttribute("RowStatusTrans");
                    if (rowStatus == 2) {
                        System.out.println("Modified Rows-" + nextRow.getAttribute("DepartmentId"));
                        revertChangesCurrentRow(nextRow);
                    } else if (rowStatus == 0) {
                        System.out.println("New Row Removed");
                        nextRow.remove();
                    }
                }
            }
            this.executeQuery();
        }
    

  • To read more about REFRESH_UNDO_CHANGES and other constants -http://docs.oracle.com/cd/B14099_19/web.1012/b14022/oracle/jbo/Row.html
  • Exposed this method to client and added it to page bindings then called it on Partial Rollback button


  • After running application, i have changed some rows of Departments table and created a new row in employees table


  • Now if i use rollback, it will also remove the new row of employees table, this is the dis-advantage of using rollback


  • Again i have changed some rows of departments table and created a new row in employees table


  • Now see when i click on partial rollback button, it will only undo changes done in department table and employee table is untouched


  • And to stay on current row after partial rollback operation just remove executeQuery from revertOrremoveRowValues() method
Download Sample App
Cheers :-)  Happy Learning

11 comments :

  1. Thanks Ashish for sharing this post .
    Can we retain the filled values of newly added row in Employee table ?,as if we perform partial rollback as you suggested user inserted data (EmpId,FirstName,LastName...)are not retaining only empty row will retain.

    ReplyDelete
    Replies
    1. No, I don't think that you can retain unsaved values
      Suppose you have changed values in a saved row then after partial rollback you'll be able to see DB values
      If you'll call partial rollback on newly created row then it'll be removed

      Ashish

      Delete
  2. Here , you are showing update and add of a row and they are getting reverted. What if I delete a row and I need that back on Cancel?

    ReplyDelete
    Replies
    1. You can use soft deletion for this requirement , check jobinesh's post - Soft Deletion of Rows

      Delete
  3. where this 'RowStatusTrans' is being set coz in my case it's throwing error defination for RowStatusTrans not found.

    ReplyDelete
    Replies
    1. It is in ViewObject RowImpl class and to set it's value code in written in getter method of variable

      Delete
  4. Hi Ashish,
    Is it possible to have partial Commit ?
    My requirement is , in jsff i have 4 VO's based on specific VO's.
    Modified all vo's , but on click of one button, wants to commit db changes only of one VO.
    If i used Commit operation, it commits all the eo's into db.
    Can you please help?
    Regards,
    Manoj

    ReplyDelete
    Replies
    1. Hi

      Commit is for whole application module so it is not possible to commit single viewObject only
      BDQ Why you want to do that ? Share your requirement may be i can help you with that or try creating separate application module for that viewObject

      Ashish

      Delete
    2. Hi,
      My requirement is-- I am having 4 VO's i.e VO1,VO2,VO3,VO4.They are having parent child relationship i.e. VO1->Multiple rows of VO2 -> Each VO2 have multiple rows of VO3 and so on. User can edit all the rows of VO3, but there is a "Save" buttom correspomding to each row. So I want to save that particular row in db irrespective of all the rows.
      I implemented this page using ViewLinks.
      One solution is to implement all the page using POJO's, but for that needs to write lot of JAVA code. So I am looking for some other alternative, if available.
      Thanks in advance.
      Regards
      Manoj

      Delete
  5. Hi Ashish,


    I have also similar requirement(Partial commit) but slightly different. Could you please check my requirement and help me.

    My requirement is : On commit operation i want to delete some selected rows but at the same time i donot want to commit newly added rows.

    Note: Actually i am handling delete operation programmatically.

    So if user adds new row into the table and then selects some rows to delete then i am able to delete rows in db but newly added row also getting committed with null values which i do not want.

    Is there any method where i can manipulate partial commits.

    Thanks,
    Mdas

    ReplyDelete
    Replies
    1. Actually you don't want to commit anything at all, then why calling commit operation just delete selected rows using row.remove() method and finally on commit save the records

      Delete