Thursday, November 25, 2010

ADF Model: Executing view accessor programatically

In this post, I'll show how to execute a VO(or it's view criteria) added as a view accessor in another VO.

Sample Use case:
For example we have two VOs DeptVO(based on only DeptEO) and EmpDeptVO(based on empEO and DeptEO) and the DeptVO is added a view accessor in EmpDeptVO and we need to programmatically execute this view accessor to get the Deptno for the passed Dname (assuming it DeptVO has a view criteria that takes Dname as a parameter or bind variable) and set the DetpNo for the newly created row in EmpDeptVO. You can download the sample application from here.

Implementation Steps:
1. Create DeptVO based on DeptEO and create a view criteria "findByDeptName" that queries based on the bind variable 'Bind_Dname'.

2. Create EmpDeptVO and add the DeptVO as view accessor (DeptVA) and select the view criteria "findByDeptName" in the VA definition.

3. Generate RowImpl class for EmpDeptVO. The generated class name will be EmpDeptVORowImpl.

4. Now, write a method say "getDeptIdFromViewAccessor" in EmpDeptVORowImpl that takes 'Dname' as parameter that executes the view accessor DeptVA and returns the DeptId for the passed 'Dname'. Code below:
public Object getDeptIdFromViewAccessor(String deptName) { //here getDeptVA is the getter for the view accessor 'DeptVA' in EmpDeptVO RowSet rowSet = this.getDeptVA(); //setting the range size to -1 to get all the rows rowSet.setRangeSize(-1); //passing the value for bind parameter for the view accessor rowSet.setNamedWhereClauseParam("Bind_Dname", deptName); //executing the view accessor rowSet.executeQuery(); //storing the first row in the row set in deptRow (there can be multiple rows in the row set based on the criteria) Row deptRow = rowSet.first(); //if the dpetRow is not null, returning the Deptno return (deptRow != null) ? deptRow.getAttribute("Deptno") : null; }


5. Call the above EmpDeptVORowImpl method in AmImpl's method say "testExecuteViewAccessor" passing the Dname for which the DeptId is required. Now, set this deptId to the newly created EmpDeptVO row in AMImpl method. Code below:
public void testExecuteViewAccessor(){ ViewObjectImpl empDeptVO = this.getEmpDeptVO(); Row row = empDeptVO.createRow(); empDeptVO.insertRow(row); EmpDeptVORowImpl empDeptRow = (EmpDeptVORowImpl)empDeptVO.getCurrentRow(); //calling the EmpDeptVORowImpl method to get the deptId for the deptName 'accounting' Object deptId = empDeptRow.getDeptIdFromViewAccessor("accounting"); System.out.println("DeptId from view accessor: "+deptId); //setting the deptId to the current row's 'Deptno' attribute. empDeptRow.setDeptno((Number)deptId); }


Here is the sample output on running this method using AM tester.

That's it. Now you know how to execute the view accessor(VA) programatically, how to pass the parameters for the view criteria selected in VA definition, how to get and use the results in AMImpl methods.

PS: DeptId and Deptno are used interchangeably in this post.

5 comments:

  1. Thanks Lot..
    This ideas help to resolved following problem 100%..


    https://forums.oracle.com/forums/thread.jspa?messageID=9919724

    Thanks Murali...:)

    ReplyDelete
  2. Hi,

    I want to create a view object with a parameter.

    can u help me

    ReplyDelete
  3. Hi Murali,
    Need help with a use case. Have a VVO in a common model project. The VVO is used to create a View Accessor in the VO of another project.
    However, the rows for such a VO is created programmatically. And a method in AM does so. We invoke the View Accessor programmatically to get the required data. Is there any downside of using such a pattern?
    Or any added advantage if we remove the VA definition from the VO and create the VA reference directly in the AM?
    The concern is because the VA is accessed only from the AM method.

    ReplyDelete
  4. Dear
    I have case to return multy records from specific view to other one can I do that

    thanks in advance

    ReplyDelete

Related Posts with Thumbnails