How to Delete Records in an OAF Page
Introduction
Deleting records is a common requirement in Oracle Application Framework (OAF) development. When working with a Search Page built on an Entity Object (EO), you can add delete functionality to allow users to remove records directly from the search results.
This guide walks you through the complete process of implementing delete functionality in an OAF page. It builds on the Search Page created in previous tutorials and covers:
Adding a Delete icon to the results table
Creating a
deleteRecordmethod in the Application ModuleConfiguring the Entity Object to support deletion
Wiring the Controller to invoke the delete method
Displaying a confirmation message after deletion
Prerequisite Reading: Creating a Search Page in OAF — https://docodi.blogspot.com/p/22-creating-oaf-search-page.html
Prerequisites
Before proceeding, ensure the following are complete:
Workspace and project RohitSearchPage created
Search Page (RohitSearchPagePG) created with a Results Table
View Object SupplierVO created and based on an Entity Object
Application Module RohitSearchPageAM created with SupplierVO attached
Controller RohitSearchPageCO created for the search page
The View Object is based on an Entity Object (mandatory for delete operations)
Important: Delete operations require an Entity Object. If your View Object is based on a plain SQL query without an EO, you cannot delete records through the standard OAF framework.
Step 1: Add a Delete Icon to the Results Table
The first step is to add a clickable delete icon to each row of the search results table.
Locate the Results Table:
Open the page RohitSearchPagePG
In the Structure pane, locate ResultsTable (under MainRN)
Create a New Item:
Right-click on ResultsTable
Select New → Item
An item (item1) is created under the ResultsTable region
Configure the Delete Icon:
Click on the newly created item1 and set the following properties in the Property Inspector:
Property Value ID DeleteIconItem Style imagePrompt DeleteImage URI deleteicon_enabled.gifAction Type firePartialActionEvent delete
Explanation:
Item Style = image: Renders the item as a clickable image
Image URI = deleteicon_enabled.gif: Uses Oracle's standard delete icon
Action Type = firePartialAction: Fires an event when clicked without a full page refresh
Event = delete: The event name that the controller will listen for
Step 2: Configure the View Object for Deletion
Before implementing the delete method, you must configure the View Object to support row-level operations. This is done by enabling the View Row Class.
Open the View Object:
In the Application Navigator, right-click on SupplierVO
Select Edit SupplierVO
Access the Java Tab:
In the View Object editor, click on the Java tab
Enable View Row Class:
Select the checkbox under View Row Class
This generates a
SupplierVORowImpl.javaclass that provides row-level methods, includingremove()
Important: Without enabling the View Row Class, the
remove()method will not be available, and the delete operation will fail.
Save the Changes:
Click OK to save the View Object configuration
Step 3: Create the deleteRecord Method in the Application Module
Now we add the deleteRecord method to the Application Module implementation class. This method performs the actual deletion.
Open the Application Module Implementation:
In the Application Navigator, click on RohitSearchPageAM
In the Structure pane, locate and double-click RohitSearchPageAMImpl.java
The Java class opens in the editor
Add the
deleteRecordMethod:
public void deleteRecord(String Column1) { OAViewObject vo = (OAViewObject)getSupplierVO(); SupplierVORowImpl row = null; int fetchedRowCount = vo.getFetchedRowCount(); RowSetIterator deleteIter = vo.createRowSetIterator("deleteIter"); if (fetchedRowCount > 0) { deleteIter.setRangeStart(0); deleteIter.setRangeSize(fetchedRowCount); for (int i = 0; i < fetchedRowCount; i++) { row = (SupplierVORowImpl)deleteIter.getRowAtRangeIndex(i); row.remove(); getTransaction().commit(); break; } } deleteIter.closeRowSetIterator(); }
Code Explanation
| Line | Purpose |
|---|---|
OAViewObject vo = (OAViewObject)getSupplierVO(); | Retrieves the SupplierVO from the Application Module |
int fetchedRowCount = vo.getFetchedRowCount(); | Gets the number of rows currently fetched |
RowSetIterator deleteIter = vo.createRowSetIterator("deleteIter"); | Creates an iterator to traverse the rows |
deleteIter.setRangeStart(0); | Starts at the first row |
deleteIter.setRangeSize(fetchedRowCount); | Sets the range to include all fetched rows |
row = (SupplierVORowImpl)deleteIter.getRowAtRangeIndex(i); | Gets the row at the current index |
row.remove(); | Marks the row for deletion |
getTransaction().commit(); | Commits the deletion to the database |
break; | Exits the loop after deleting one row |
deleteIter.closeRowSetIterator(); | Closes the iterator to release resources |
Note: The
breakstatement ensures only the selected row is deleted. In a multi-select scenario, you would remove thebreakand iterate through all selected rows.
Step 4: Write the Controller Code
Now we add code to the Controller to handle the delete event and invoke the deleteRecord method.
Open the Controller:
In the Application Navigator, double-click on RohitSearchPageCO
Add the Following Code in Process Form Request:
if ("delete".equals(pageContext.getParameter(EVENT_PARAM))) { OAApplicationModule am = (OAApplicationModule)pageContext.getApplicationModule(webBean); am.invokeMethod("DeleteRecord", null); throw new OAException("Record Deleted Successfully", OAException.INFORMATION); }
Code Explanation
| Line | Purpose |
|---|---|
if ("delete".equals(pageContext.getParameter(EVENT_PARAM))) | Checks if the delete event was fired |
OAApplicationModule am = ... | Retrieves the Application Module |
am.invokeMethod("DeleteRecord", null); | Invokes the deleteRecord method on the AM |
throw new OAException(...) | Displays a confirmation message to the user |
Important: The
OAExceptionwithOAException.INFORMATIONis used to display an informational message. This is a common OAF pattern for showing success messages.
Step 5: Rebuild and Run the Project
Rebuild the Project:
Right-click on the project RohitSearchPage
Select Rebuild
Note: Rebuilding compiles all Java classes and ensures there are no errors before deployment.
Run the Search Page:
After successful compilation, right-click on RohitSearchPagePG
Select Run
Test the Delete Functionality:
The search page opens in your browser
Enter search criteria and click Go to retrieve records
Click the Delete icon next to a record
The record is deleted, and a confirmation message appears: "Record Deleted Successfully"
How the Delete Operation Works at Runtime
The following illustrates the complete delete flow:
┌─────────────────────────────────────────────────────────────────┐
│ SEARCH PAGE │
│ 1. User searches and views results in the table │
│ 2. Each row has a Delete icon (deleteicon_enabled.gif) │
│ 3. User clicks the Delete icon on a specific row │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ CONTROLLER (RohitSearchPageCO) │
│ 1. Detects "delete" event via EVENT_PARAM │
│ 2. Retrieves the Application Module │
│ 3. Invokes "DeleteRecord" method │
│ 4. Throws OAException with success message │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ APPLICATION MODULE (RohitSearchPageAMImpl) │
│ 1. Gets SupplierVO │
│ 2. Creates RowSetIterator │
│ 3. Gets the row at the current index │
│ 4. Calls row.remove() to mark for deletion │
│ 5. Commits the transaction │
│ 6. Closes the iterator │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ DATABASE │
│ 1. DELETE statement executed │
│ 2. Record permanently removed │
│ 3. Confirmation message displayed to user │
└─────────────────────────────────────────────────────────────────┘Understanding the Delete Mechanism
| Component | Role | Key Method/Property |
|---|---|---|
| Delete Icon | Triggers the delete event | firePartialAction, Event=delete |
| View Row Class | Enables row-level operations | View Row Class checkbox |
| Application Module | Performs the actual deletion | deleteRecord() method |
| View Object | Provides the row to delete | getSupplierVO() |
| Controller | Handles the event and invokes the method | invokeMethod("DeleteRecord", null) |
Why the View Row Class is Required
The View Row Class (SupplierVORowImpl) is essential for delete operations because:
It provides the
remove()method that marks a row for deletionWithout it, the View Object is read-only and cannot participate in DML operations
It inherits from
OAViewRowImpl, which provides the standard OAF row-level functionality
How the Row is Identified
In this implementation, the deleteRecord method deletes the first row in the iterator (using break after the first removal). In a real-world scenario, you would typically:
Pass the row's primary key to the
deleteRecordmethodLocate the specific row using
findByKey()or a similar methodRemove only that row
For example, a more robust implementation would be:
public void deleteRecord(String supplierId) { OAViewObject vo = (OAViewObject)getSupplierVO(); Row[] rows = vo.findByKey(new Key(new Object[]{supplierId}), 1); if (rows != null && rows.length > 0) { rows[0].remove(); getTransaction().commit(); } }
Note: The simpler implementation in this guide assumes the user is deleting the first row. For a production application, always delete by primary key.
Best Practices
| Practice | Description |
|---|---|
| Confirm Before Delete | Always ask for confirmation before deleting a record |
| Use Primary Keys | Delete by primary key, not by row index |
| Handle Errors | Add try-catch blocks for database errors |
| Provide Feedback | Display a success message after deletion |
| Refresh the Results | Re-execute the query to show updated results |
| Restrict Access | Use privileges to control who can delete records |
| Log Deletions | Maintain an audit trail of deleted records |
Troubleshooting Common Issues
| Issue | Possible Cause | Solution |
|---|---|---|
| Delete icon doesn't appear | Wrong Image URI | Verify deleteicon_enabled.gif exists |
| Delete event not firing | Wrong Action Type | Set Action Type to firePartialAction |
remove() method not available | View Row Class not enabled | Enable View Row Class in VO |
| Record not deleted | Commit not called | Verify getTransaction().commit() is invoked |
| Wrong record deleted | Deleting by index | Delete by primary key instead |
| Compilation errors | Missing imports | Add imports for RowSetIterator, OAException, etc. |
| No confirmation message | OAException not thrown | Verify the throw new OAException(...) statement |
Required Import Statements
import oracle.apps.fnd.framework.OAApplicationModule; import oracle.apps.fnd.framework.OAException; import oracle.apps.fnd.framework.OAViewObject; import oracle.apps.fnd.framework.server.OAViewObjectImpl; import oracle.apps.fnd.framework.webui.OAPageContext; import oracle.apps.fnd.framework.webui.OAControllerImpl; import oracle.apps.fnd.framework.webui.beans.OAWebBean; import oracle.jbo.RowSetIterator; import oracle.jbo.server.ViewRowImpl;
Summary
Deleting records in an OAF page involves the following key steps:
Add a Delete Icon: Create an image item in the results table with
firePartialActionandEvent=deleteConfigure the View Object: Enable the View Row Class to support row-level operations
Create the deleteRecord Method: Add a method to the Application Module that removes the row and commits
Write Controller Code: Handle the
deleteevent and invoke thedeleteRecordmethodDisplay Confirmation: Throw an
OAExceptionwith an informational messageRebuild and Test: Compile and verify the delete functionality
The key insight is that delete operations in OAF require:
An Entity Object: To handle the actual DML operation against the database
A View Row Class: To provide the
remove()method on the View Object's rowsA Commit: To permanently save the deletion to the database
This pattern—using a deleteRecord method in the AM, invoked by the controller in response to a firePartialAction event—is the standard approach for implementing delete functionality in Oracle E-Business Suite applications.
For production applications, always enhance this basic pattern with:
Confirmation dialogs before deletion
Deletion by primary key (not row index)
Proper error handling and logging
Access control to restrict who can delete records
References
Prerequisite: Creating a Search Page in OAF — https://docodi.blogspot.com/p/22-creating-oaf-search-page.html
Related: Creating a Data Entry Page in OAF
Related: Update Page in OAF Framework
Oracle E-Business Suite Documentation: OA Framework Developer's Guide
Oracle JDeveloper Documentation: Available in the
jdevdocfolderOracle Application Framework: Official Oracle documentation
No comments:
Post a Comment