Quick Overview of New BC4J 9.0.4 Range Paging Feature

Send me a mail
 Dive into Oracle ADF   Click to see the XML version of this web page.   (Updated: 2/3/2008; 9:24:23 PM.)
Tips and tricks from Steve Muench on Oracle ADF Framework and JDeveloper IDE

Quick Overview of New BC4J 9.0.4 Range Paging Feature

The Range-Paging feature, available beginning in release 9.0.4 of BC4J, allows you to process a set of rows at a time.  Unlike the default mode, the RowSet will not continue to accumulate rows in the view row cache as you fetch them. Thus, you put a cap on the memory used by this rowset to a single "range-size" page full of rows. Also, compared to forward-only, you have the added benefit that you can scroll backwards. That is, calling the previous() method will work in this mode while it throws an exception in forward-only mode.

This feature is controlled through a new API on the oracle.jbo.RowSet interface.

public void setAccessMode(byte mode);
public byte getAccessMode();

The "mode" parameter specifies how the rows are scanned and cached in the collection.

Specifically, the following contstants are available for the access mode.

public static byte SCROLLABLE
public static byte FORWARD_ONLY
public static byte RANGE_PAGING
public static byte RANGE_PAGING_AUTO_POST
  • SCROLLABLE - RowSet should fetch rows and cache the ViewRows in a collection. This is the most flexible mode for accessing rows and working with a RowSet.  This allows scrolling backwards.  However, if you fetch too many rows, you may run out of memory or cause spill-to-disk to kick in. This is the default.
  • FORWARD_ONLY - RowSet should only provide sequential access to Rows in its collection.  The iterators on this RowSet will not allow scrolling back.  Internally, the collection keeps only one row (the current one). If you insert a new row into a forward-only RowSet, that row becomes the current row.
  • RANGE_PAGING - RowSet should fetch rows in ranges (set using setRangeSize()), such that on scroll to the the next range or to fetch a row that's not in the current range, a database query using ROWNUM virtual column is used.  And, the row at the desired index is placed as the first row in the current range. New rows inserted in this mode will be inserted at the beginning of the rowset

    For example, suppose you start with rows: row0, row1,..., row19, where the RowSet is seeing row2 - row 11 (range size = 10).  This means the RowSet only has row2 - row11 in the view row cache.

    If you insert a new row rowNew0, your RowSet will become

          rowNew0 -- index 0
          row0 -- index 1 now
          row1 -- index 2 now
          ..
          row19 -- index 20 now

       If you insert another new row rowNew1, your RowSet will become:

          rowNew0 -- index 0
          rowNew1 -- index 1
          row0 -- index 2 now
          row1 -- index 3 now
          ..
          row19 -- index 21 now
  • RANGE_PAGING_AUTO_POST - Same as RANGE_PAGING, except that when you ask for the new set of rows from the RowSet, a check is made to see if either new rows have been inserted or an old rows have been removed.  If so, the changes are written to database.


Here is a sample block of code.  Suppose we have Emp table with > 10 rows:

ViewObject voEmp = myAM.findViewObject("Emp");
Row row;
voEmp.setAccessMode(RowSet.RANGE_PAGING);
while ((row = voEmp.next()) != null) {
   System.out.println("Emp: " + row.getAttribute("Ename"));
}
System.out.println("-------------------------------");
System.out.println("Now GO BACKWARDS");   
while ((row = voEmp.previous()) != null) {
   System.out.println("Emp: " + row.getAttribute("Ename"));
}

If you run a code block like the above with diagnostic turned on (-Djbo.debugoutput=console), you should be able to see the queries that the BC4J issues, including the additional query "wrappering" that BC4J generates to get the database to return only the current page of records.



© Copyright 2008 Steve Muench. Click here to send an email to the editor of this weblog.
Last update: 2/3/2008; 9:24:23 PM.