Building programmatically managed business components - Part 2

Putting in to action

We have seen the basic theory behind the execution of  entity and view objects in the first part of this article. In the second part , let us put the theory in to action.

Download

You can download the sample workspace from here.
[Runs with Oracle JDeveloper 11.1.2.0.0 (11g R2) + HR Schema]
Please note this example does not use any API specific to 11.1.2.0 release, so you may be able to reuse the source classes in previous versions also.

A glance at the implementation

This example uses two model objects - Department and Employee. The 'Department' is based on DEPARTMENTS table and it follows usual entity and view object generation steps, whereas Employee is based on custom data source and the steps for generating programmatically managed Employee model object is given below.

Building base classes for your programmatic entity and view objects

While building a programmatic view or entity objects you may need to hook your code to perform CRUD (Create Read Update Delete) operations against the custom data source (as per your use case) by overriding the life cycle methods(by default CRUD is done against database). This example uses generic base classes for doing this job and they are copied below for your reference.


ProgrammaticallyManagedEntityObjectImpl : Abstract entity object which overrides EntityImpl::doDML(...) and related methods.
ProgrammaticallyManagedViewObjectImpl : Abstract view object which overrides ViewObjectImpl::executeQueryForCollection(...) and related methods.
GenericQueryModel : A generic query model class which holds the filtering criteria  for third party services.
GenericRowCollection : A generic data structure to hold the result from the query(data retrieval) execution.
GenericRowData : A generic data structure representing a row in the result set.

Building programmatic entity object

Step 1: Right click the model  project, select New->ADF Business Components-> Entity Objects. You can key in the entity name and leave the default values for the other fields as is, click Next.


Step 2: Add attributes and finish the wizard


Step 3: Select the generated entity object in the editor, go to Java tab and click on edit Java Options. Change the base class for the Entity Object as fmwk.extension.entity.ProgrammaticallyManagedEntityObjectImpl(what we generated initially)
You may need to override ProgrammaticallyManagedEntityObjectImpl::getService() to return GenericDataPersistanceService implementation. Please see Step 4 for the service implementation.

Step 4: Build the business service implementing fmwk.extension.view.GenericDataPersistanceService for updating the data. Please take a look at model.emp.service.MyEmpDataServiceImplementation to get a feel of the implementation.

Building programmatic view object

Step 1: Select the programmatic entity object, right click and then select New Default View Object option from the context menu.


Step 2: Switch to the source mode of the generated view object and set the CustomQuery="true" as shown in the following image. This is very important step as this flag influences the run time to avoid the query execution against data base(which is the default execution path)


Ste 3: Select the generated view object in the editor, go to Java tab and click on edit Java Options. Change the base class for the View Object as fmwk.extension.entity.ProgrammaticallyManagedViewObjectImpl(what we generated initially)


You may need to override ProgrammaticallyManagedViewObjectImpl::getService() to return GenericDataReadServiceInterface implementation. Please see Step 4 for the service implementation.

Step 4: Build the business service to read data by implementing fmwk.extension.view.GenericDataReadService.  Please take a look at model.emp.service.MyEmpDataServiceImplementation to get a feel of the implementation.

Can I reuse this sample source?

Well, the classes what you see in package fmwk.extension.xxx are generic in nature and reusable. If you have similar use cases, then you may need to implement an adapter for your 'data source' calls as shown in model.emp.service.MyEmpDataServiceImplementation. The core run time classes what you see under fmwk.extension.xxx can be reused either as is or with some modifications.

How to run this sample?

This example is based on Department-Employee model. As I said earlier the Department is based on data base table and Employee is programmatically manged. This sample contains three pages illustrating search, update and master-child coordination on programmatic view object.
  • search.jsf - Search page for programmatic view object.
  • masterChild - Master child coordination(Department-Employee) through view link.
  • edit.jsf - Edit page for programmatic entity object.
Learn More ...
There are a lot more points like this. If  you are curious to learn the internals of the ADF Business Components and ADF Binding Layer,  the following book is for you - Oracle ADF Real World Developer’s Guide.
More details about this book can be found in this post- http://jobinesh.blogspot.in/2012/07/pre-order-your-copy-of-oracle-adf-real.html

Comments

  1. Thanks for this article..has given me an idea to proceed with my work :)

    ReplyDelete
  2. Hi,
    I have tried to create a programmatic VO without an entity object. But I am stuck up in the end. I have posted a thread in otn regarding this.
    forums.oracle.com/forums/thread.jspa?messageID=10750158#10750158
    Can you help me with this?

    ReplyDelete
  3. Hi,

    I have downloaded the sample but I am struggling to understand what do I need to do and what methods to implement in order to achieve ViewLink functionality between 2 programatically view objects. Can you kindly let me know which methods I need to focus on?

    ReplyDelete
  4. Hi, I have a Prog VO. A button click queries a set of flat files to retrieve data. There are bind variables to execute query. I have set rangesize to default. And max size of 250 to ResultSet in the VO. Everything works fine until query returns 25 rows. Once Query returns more than 25 rows,and I re-query, here is what happens
    1. Query is executed more than once in the VO.As a result, bind variables are not applied.
    2. max size set on VO is also overridden.
    3. Scroll on adf table doesn't point to last row.(I have set displayrows=last in page fragment)
    4. If I try to scroll the scroll bar on table - VO populates rows - these are not the right set of rows. Precisly, bind variables were not applied.
    Could you let me know what am I missing here ?
    Also getQueryHitCount() may or may not get executed. It returns wrong #(count) of rows

    ReplyDelete
  5. Hi Jobinesh,

    I used your solutions and it works perfectly.

    Now I need to add LOV to my programmatically managed view object. The other view object that I am referencing in my LOV is normal view object (not programmatic).

    After I added the LOV, added a form of prog. vo into a jsf page, I got the error given below:

    incident 10 created with problem key "DFW-99998 [oracle.jbo.KeyNotPopulatedException][oracle.jbo.server.OracleSQLBuilderImpl.buildWhereClause][j2ee-app]"


    What can be the problem is?

    ReplyDelete

Post a Comment