Skip navigation
Hello ,

 

There are times in development when we have to show tables with large number of rows to user on the Page. ADF table contains very good property of Scroll which fetches the data from the database when the user scrolls in the table.
This works well when the number of rows in the table is less i.e we can say around 4-5000 without much problem. But the problem begins when we have Thousands or Lacks of rows in the table.

 

On the default settings when you scroll to the 10000th row then the table fetches all the data upto the 10000th row and then shows the results in the table. When the table starts fetching the 10000 rows in the memory then it takes time , here comes the problem. So if we can reduce this time then we can solve the problem.

 

Before solving the problem first we need to know why this problem comes into picture.
The problem is that when the user scrolls on the 10000th row, the framework start loading all the 10000 rows in the memory to show on the page, and this takes time.
For avoiding this problem we can customize the setting in ViewObject tuning section.
Go to the Tuning section of any ViewObject, you will see following options .

 


We have to focus on following properties.

 

# Retrieve rows from the database : It can be set to :

 

  1. All Rows (All the rows will be fetch at a time, when the number of rows are large then it takes so much time.)
  2. Only upto row number (Makes sure that only the rows upto the given number are fetched)
  3. in batches of (It defines the number of rows fetched in one roundTrip to database. Its value depends on the use case but I this case we keep it to n+1, where n is the number of rows to be shown on the page. )
# Access Mode (This is the property to be concerned)
  1. Scrollable : when acess mode is scrollable it means as the user scrolls all the rows upto which user have scrolled will be loaded in the memory before it is shown on the page.
  2. Page Ranging : when the access mode is Page Ranging then when the user scrolls upto some row then only the rows that need to be displayed currently are loaded in to the memory. Let us take an example. Suppose the user scrolls to 10000th row then the RANGE containing row number 10000 will only get loaded into the memory.
So less time needed to load the rows hence table loads faster

# Range size
It defines the range, We keep the range size to n+1 where n is the number of rows that the user needs to show on the page.
Range size basically means the number of rows that will be loaded from the viewObject cache to the binding. This is kept to n+1 because if the we don't want more than one round trip to database as if the range size increases the fetch size then an another roundTrip to fetch values in issued.
Also keep the range of the table in sync with the range size of of the table, it helps.
This post is relating to the error that often comes on ADF Applications.
Error : oracle.jbo.RowInconsistentException: JBO-25014: Another user has changed the row with primary key
Main Cause :
This comes up when user commits the data on ADF page, the framework checks whether if the row which is being modified and being committed by the current user is still in the same state as it was when the framework fetched the row from the database.
Scenario :
  1. Suppose a      user A     wants to modify the Salary of an Employee with Employee_id 10.
  2. He picks the row and started      editing the record and sets the Salary to 3500.
  3. Meanwhile a new user B who also wanted to update      the Salary of Employee_id 10 picks the record and edits the record and      sets the Salary to 3000, and commits the record.
  4. Now if the user A commits the record then this      error will appear.
    • This will appear as when the       user A      started editing the record, at that time framework made a copy of same       record and kept with it.
    • When the user A completed its entry and try       to commit the record, then the framework compares the record saved with       it and the same record currently in the database.
    • This is to ensure that while       the user A was editing the data then the same record was not modified by       any other user. This done to maintain the consistency of the database.
    • As if the A is allowed to commit the       data then the changes made by B will be lost.
    • This is the scenario in case       of Optimistic Locking Mechanism. If you want to know more about Locking       mechanism http://adfjavacodes.blogspot.in/2014/04/adf-alternate-of-current-row-selection.html
Normally this is case. But in ADF Applications this comes up even if the Another User is not modifying the record.
Here are some of the causes :
  1. Formatting      in case of Date Columns.
    • Problem : Suppose the Date saved as       timestamp in database as '12-11-2015 11:10:55.001' and in the ADF       Application it is '12-11-2015 11:10:55'. Ideally they are same but for       the framework this is a mismatch.
    • Solution : The trick to avoid this error is to send       the data in the database after the formatting i.e.  '12-11-2015 11:10:55' so that on       comparison it compares '12-11-2015 11:10:55.000'  and '12-11-2015 11:10:55'
  2. Formatting in case of Number      Columns.
  3. PostChanges() being called in      the application.
    1. Problem :      Data is posted to the database in case of PostChanges(). And if after       that the data is modified then again this comes as there is difference       between database and framework. Suppose the value of a column is 'A'       before postChanges and afterwards it is changed to 'B'. Then on commit       this comes up, not always but often in case of PostChanges.
    1. Solution : This is no particular sure solution to       this, but we have certain options
      1. Executing the VO before commit.
      2. We can use Refresh on Insert, Refresh on Modifiy        attributes of Entity. Set it to true to avoid this error.
Now as we have done the homework :) regarding this, now It’s a task to identify that on which attribute this error is coming.  Here are the steps.
  1. Start the      server.
  2. Go To we logic server console      | Actions-> Configure Oracle Diagnostic Logging

  1. Now go set      the log to finest for oracle.jbo to finest

  2. Now go to preference in      Jdeveloper and increase the log lines to 30000 as too many log rows will      be generated.
  3. Now clear the log before the      event on which this error occurs then       perform the event.
  4. Then in the log search for      text 'Entity Compare failed' and it will show you the attribute name for      which this error is appearing and Value.
Hi,

Here I am going to demonstrate how we can create a n-level Tree table by populating data from the bean.
Here are the steps that need to be followed.
  1. For     creating this we need to create a datatype for storing the values of     the  row or we call it node in     TreeTable. Here is the code for the datatype or POJO class named     TreeNodeDS.
    package testtabledemoapp.view.treeds;
    import java.util.ArrayList;
    public class TreeNodeDS {    private String id;    private String description;    private ArrayList<TreeNodeDS> child = new ArrayList<TreeNodeDS>();
        public void setId(String id) {        this.id = id;    }
        public String getId() {        return id;    }
        public void setDescription(String description) {        this.description = description;    }
        public String getDescription() {        return description;    }
        public void setChild(ArrayList<TreeNodeDS> child) {        this.child = child;    }
        public ArrayList<TreeNodeDS> getChild() {        return child;    }
        public TreeNodeDS(String id,String description) {        super();        this.id = id;        this.description = description;    }    
        public void addNewChild(TreeNodeDS treeNodeDS){        child.add(treeNodeDS);        
        }}
  2. Here is the code in the bean     the bean.

    package testtabledemoapp.view.bean;
    import java.util.ArrayList;
    import org.apache.myfaces.trinidad.model.ChildPropertyTreeModel;
    import testtabledemoapp.view.treeds.TreeNodeDS;
    public class TreeNodeBean {    private ArrayList<TreeNodeDS> list = new ArrayList<TreeNodeDS>();    ChildPropertyTreeModel charatcerVal = null;
        public ChildPropertyTreeModel getCharatcerVal() {        return charatcerVal;    }
        public TreeNodeBean() {        super();        TreeNodeDS firstNode = new TreeNodeDS("F001","First Level");        TreeNodeDS secondNode = new TreeNodeDS("F002","Second Level");        TreeNodeDS thirdNode = new TreeNodeDS("F003","Third Level");        TreeNodeDS fourthNode = new TreeNodeDS("F004","Fourth Level");        firstNode.addNewChild(secondNode);        secondNode.addNewChild(thirdNode);        thirdNode.addNewChild(fourthNode);        list.add(firstNode);        list.add(secondNode);        list.add(thirdNode);        list.add(fourthNode);        list.add(secondNode);      //Initialising the character val with the data        charatcerVal = new ChildPropertyTreeModel(list,"child");    }}
  3. Now create a treeTable on the     page. Here is the code of the page.

    <af:link text="#{node.id}" id="l1"                                         inlineStyle="#{node.description == '' ? 'font-weight:500;color:navy' : ''}"                                         rendered="true"/>                                <af:outputText value="#{node.id} | #{node.description}" id="ot1" rendered="false"/>                                <af:link text="#{node.description}" id="l2" rendered="true"/>
  4. Now run the application. Here     is the screen shot.
    Here is the same Application : TreeTableDemoApp