- Oracle JDeveloper 11gR2 Cookbook
- Nick Haralabidis
- 1122字
- 2025-04-04 23:25:00
Iterating a view object using a secondary rowset iterator
There are times when you need to iterate through a view object rowset programmatically. In this recipe, we will see how to do this using a secondary rowset iterator. We will iterate over the Employees
rowset and increase the employee's commission by a certain percentage for each employee that belongs to the Sales department.
Getting ready
This recipe was developed using the HRComponents
workspace, which was created in the Overriding remove() to delete associated children entities recipe in Chapter 2, Dealing with Basics: Entity Objects. The HRComponents
workspace requires a database connection to the HR
schema.
How to do it...
- Open the
Employees
view object definition and go to the Java page. - Click on the Edit java options button (the pen icon) to open the Select Java Options dialog.
- Click on the Generate View Object Class and Generate View Row Class checkboxes. Ensure that the Include accessors checkbox is also selected.
- Click OK to proceed with the creation of the custom implementation classes.
- Add the following helper method to
EmployeesImpl.java
. If the import dialog is shown for theNumber
class, make sure that you choose theoracle.jbo.domain.Number
class.public void adjustCommission(Number commissionPctAdjustment) { // check for valid commission adjustment if (commissionPctAdjustment != null) { // create an employee secondary rowset iterator rowsetIterator employees = this.createrowsetIterator(null); // reset the iterator employees.reset(); // iterate the employees while (employees.hasNext()) { // get the employee EmployeesRowImpl employee = (EmployeesRowImpl)employees.next(); // check for employee belonging to the sales department if (employee.getDepartmentId() != null &&SALES_DEPARTMENT_ID ==employee.getDepartmentId().intValue()) { // calculate adjusted commission Number commissionPct = employee.getCommissionPct(); Number adjustedCommissionPct = commissionPct != null) ? commissionPct.add(commissionPctAdjustment) : commissionPctAdjustment; // set the employee's new commission employee.setCommissionPct(adjustedCommissionPct); } } // done with the rowset iterator employees.closerowsetIterator(); } }
- On the Employees Java page click on the Edit view object client interface button (the pen icon).
- On the Edit Client Interface dialog, shuttle the
adjustCommission()
method to the Selected list and click OK. - Open the
HRComponentsAppModule
application module definition and go to the Java page. - Click on the Edit java options button.
- On the Select Java Options dialog, click on the Generate Application Module Class checkbox. Then click OK to close the dialog.
- Open the
HrComponentsAppModuleImpl
class and add the following method:public void adjustCommission(Number commissionPctAdjustment) { // execute the Employees view object query to create a rowset this.getEmployees().executeQuery(); // adjust the employees commission this.getEmployees().adjustCommission(commissionPctAdjustment); }
- Return to the application module definition Java page, then use the Edit application module client interface button to add the
adjustCommission()
method to the application module's client interface.
How it works...
We created a view object custom Java implementation class for the Employees
view object and add a method called adjustCommission()
. The method is then exposed to the view object's client interface so that it can be accessible and called using the Employees
interface.
The adjustCommission()
method adjusts the commission for all employees belonging to the Sales department. The method accepts the commission adjustment percentage as an argument. We call the createrowsetIterator()
method to create a secondary iterator, which we then use to iterate over the Employees
rowset. This is the recommended practice to perform programmatic iteration over a rowset. The reason is that the view object instance that is being iterated may be bound to UI components and that iterating it directly will interfere with the UI. In this case, you will see the current row changing by itself.
We then call the reset()
method to initialize the rowset iterator. This places the iterator in the slot before the first row in the rowset. We iterate the rowset by checking whether a next row exists. This is done by calling hasNext()
on the iterator. If a next row exists, we retrieve it by calling next()
, which returns an oracle.jbo.Row
. We cast the default Row
object that is returned to an EmployeesRowImpl
, so we can use the custom setter and getter methods to manipulate the Employee
row.
For testing purposes, we create a custom application module implementation class and add a method called adjustCommission()
to it. We expose this method to the application module client interface so that we can call it from the ADF Model Tester . Note that methods can also be added to the view object client interface. Then these methods are shown under the view object collection in the Data Control panel and can be bound to the JSF page simply by dropping them on the page. Inside the adjustCommission()
, we execute the Employees
view object query by calling executeQuery()
on it. We get the Employees
view object instance via the getEmployees()
getter method. Finally, we call the adjustCommission()
method that we implemented in EmployeesImpl
to adjust the employees' commission.

There's more...
In order to be able to iterate a view object rowset using a secondary iterator, the view object access mode in the General | Tuning section must set to Scrollable
. Any other access mode setting will result in a JBO-25083: Cannot create a secondary iterator on row set {0} because the access mode is forward-only or range-paging error when attempting to create a secondary iterator. To iterate view objects configured with range paging, use the range paging view object API methods. Specifically, call getEstimatedRangePageCount()
to determine the number of pages and for each page call scrollToRangePage()
. Then determine the range page size by calling getRangeSize()
and iterate through the page calling getRowAtRangeIndex()
.
Before iterating a view object rowset, consider that iterating the rowset may result in fetching a large number of records from the database to the middle layer. In this case, other alternatives should be considered, such as running the iteration asynchronously on a separate Work Manager , for instance (see recipe Using a Work Manager for processing of long running tasks in Chapter 12, Optimizing, Fine-tuning and Monitoring). In certain cases, such as when iterating in order to compute a total amount, consider using any of the following techniques. These methods are far more optimized in determining the total amount for an attribute than iterating the view object using Java code.
For instance, consider the following view object query that calculates the department's total salaries using an analytic function. This would have been much more costly if it had to be done programmatically by iterating the underlying view objects.
SELECT DISTINCT DEPARTMENTS.DEPARTMENT_NAME, SUM (EMPLOYEES.SALARY) OVER (PARTITION BY EMPLOYEES.DEPARTMENT_ID) AS DEPARTMT_SALARIES FROM EMPLOYEES INNER JOIN DEPARTMENTS ON DEPARTMENTS.DEPARTMENT_ID = EMPLOYEES.DEPARTMENT_ID ORDER BY DEPARTMENTS.DEPARTMENT_NAME
See also
- Overriding remove() to delete associated children entities, Chapter 2, Dealing with Basics: Entity Objects