20. Delete Records in OAF Page

 

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:

  1. Adding a Delete icon to the results table

  2. Creating a deleteRecord method in the Application Module

  3. Configuring the Entity Object to support deletion

  4. Wiring the Controller to invoke the delete method

  5. 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.

  1. Locate the Results Table:

    • Open the page RohitSearchPagePG

    • In the Structure pane, locate ResultsTable (under MainRN)

  2. Create a New Item:

    • Right-click on ResultsTable

    • Select New → Item

    • An item (item1) is created under the ResultsTable region

  3. Configure the Delete Icon:

    Click on the newly created item1 and set the following properties in the Property Inspector:

    PropertyValue
    IDDeleteIcon
    Item Styleimage
    PromptDelete
    Image URIdeleteicon_enabled.gif
    Action TypefirePartialAction
    Eventdelete

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.

  1. Open the View Object:

    • In the Application Navigator, right-click on SupplierVO

    • Select Edit SupplierVO

  2. Access the Java Tab:

    • In the View Object editor, click on the Java tab

  3. Enable View Row Class:

    • Select the checkbox under View Row Class

    • This generates a SupplierVORowImpl.java class that provides row-level methods, including remove()

Important: Without enabling the View Row Class, the remove() method will not be available, and the delete operation will fail.

  1. 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.

  1. 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

  2. Add the deleteRecord Method:

java
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

LinePurpose
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 break statement ensures only the selected row is deleted. In a multi-select scenario, you would remove the break and 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.

  1. Open the Controller:

    • In the Application Navigator, double-click on RohitSearchPageCO

  2. Add the Following Code in Process Form Request:

java
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

LinePurpose
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 OAException with OAException.INFORMATION is used to display an informational message. This is a common OAF pattern for showing success messages.


Step 5: Rebuild and Run the Project

  1. 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.

  1. Run the Search Page:

    • After successful compilation, right-click on RohitSearchPagePG

    • Select Run

  2. 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:

text
┌─────────────────────────────────────────────────────────────────┐
│                     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

ComponentRoleKey Method/Property
Delete IconTriggers the delete eventfirePartialAction, Event=delete
View Row ClassEnables row-level operationsView Row Class checkbox
Application ModulePerforms the actual deletiondeleteRecord() method
View ObjectProvides the row to deletegetSupplierVO()
ControllerHandles the event and invokes the methodinvokeMethod("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 deletion

  • Without 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:

  1. Pass the row's primary key to the deleteRecord method

  2. Locate the specific row using findByKey() or a similar method

  3. Remove only that row

For example, a more robust implementation would be:

java
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

PracticeDescription
Confirm Before DeleteAlways ask for confirmation before deleting a record
Use Primary KeysDelete by primary key, not by row index
Handle ErrorsAdd try-catch blocks for database errors
Provide FeedbackDisplay a success message after deletion
Refresh the ResultsRe-execute the query to show updated results
Restrict AccessUse privileges to control who can delete records
Log DeletionsMaintain an audit trail of deleted records

Troubleshooting Common Issues

IssuePossible CauseSolution
Delete icon doesn't appearWrong Image URIVerify deleteicon_enabled.gif exists
Delete event not firingWrong Action TypeSet Action Type to firePartialAction
remove() method not availableView Row Class not enabledEnable View Row Class in VO
Record not deletedCommit not calledVerify getTransaction().commit() is invoked
Wrong record deletedDeleting by indexDelete by primary key instead
Compilation errorsMissing importsAdd imports for RowSetIterator, OAException, etc.
No confirmation messageOAException not thrownVerify the throw new OAException(...) statement

Required Import Statements

java
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:

  1. Add a Delete Icon: Create an image item in the results table with firePartialAction and Event=delete

  2. Configure the View Object: Enable the View Row Class to support row-level operations

  3. Create the deleteRecord Method: Add a method to the Application Module that removes the row and commits

  4. Write Controller Code: Handle the delete event and invoke the deleteRecord method

  5. Display Confirmation: Throw an OAException with an informational message

  6. Rebuild 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 rows

  • A 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 jdevdoc folder

  • Oracle Application Framework: Official Oracle documentation

No comments:

Post a Comment