Thursday, December 17, 2015

Rollback before navigation between pages is done

When you want to rollback any transaction before navigate to another page:
1- Create class that extends class called NavigationHandler then
    override method called handleNavigation as follows:


public class CustomNavigationHandler  extends NavigationHandler{
  
    private NavigationHandler navHandler=null;
  
    public CustomNavigationHandler(NavigationHandler navHandler)
    {
        super();
        this.navHandler=navHandler;
      
    }
    public void handleNavigation(FacesContext ctx,String action,String outcome){
        if (outcome !=null){
            ADFUtils.getAppImpl("AppModuleAM").getDBTransaction().rollback();
        }
        navHandler.handleNavigation(ctx,action,outcome);
    }   
}

2- Register the class at the faces-config.xml file as follows:

Sunday, December 13, 2015

Rollback specific page when navigating from it

UseCase
When you create new row in a page and start to set a form values then navigate to another page then commit the validation of the row at first page will be fired , you want to rollback any transaction on the first page when navigate to anther page.
We want to rollback when navigating out of a target specific page.
Solution
1- At first page (target),when click CreateInsert button, set a value for a session variable with name viewIdd
2- Create class that implements PagePhaseListener.
3-Override afterPhase method and make rollback if the session variable was set and the target page has changed.
public class MyPageListener implements PagePhaseListener {
    @Override
    public void afterPhase(PagePhaseEvent pagePhaseEvent) {
        int phaseId = pagePhaseEvent.getPhaseId();
        // if the variable was set and the current page isn't the target page
        if (JSFUtils.getFromSession("viewIdd") != null &&
       !FacesContext.getCurrentInstance().getViewRoot().getViewId().contains("TargetPage")) {
            // Lifecyce.getPhaseName(phaseId) == 
              if (Lifecycle.getPhaseName(phaseId) == Lifecycle.PREPARE_RENDER_ID) {
                ADFUtils.getAppImpl().getDBTransaction().rollback();
                ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
                HttpSession session = (HttpSession) context.getSession(false);
                if (session != null) {
                    session.removeAttribute("viewIdd");
                    //  JSFUtils.setManagedBeanValue("#{sessionScope.viewIdd}", null);
                }
            }
        }
    }

3- Register the class as a listener in /METAINF/adf-settings file located at Application Resources
<?xml version="1.0" encoding="US-ASCII" ?> 
<adf-settings xmlns="http://xmlns.oracle.com/adf/settings"> 
  <adfc-controller-config xmlns="http://xmlns.oracle.com/adf/controller/config"> 
    <lifecycle> 
      <phase-listener> 
        <listener-id>MyPageListener1</listener-id> 
        <class>view.MyPageListener</class> 
        <before-id-set> 
          <listener-id> MyPageListener1</listener-id> 
        </before-id-set> 
        <after-id-set> 
          <listener-id>MyPageListener1</listener-id> 
        </after-id-set> 
     </phase-listener> 
    </lifecycle> 
  </adfc-controller-config> 
</adf-settings>

Performing Partial Rollback

http://www.awasthiashish.com/2014/04/performing-partial-rollback-undo.html

UseCase
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.
Solution
1-  add a new transient attribute in Departments Vo to get current state of each row
/**
     * 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);
    }

2- create 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();
    }

java - fill distinct objects in ArrayList

If you have a list that contains some objects that it is considered as duplication when two or three fields of these objects are equal. How ...