Forcing Task Flow instances with Shared Data Control to use different view object instances

If you have have a task flow designed to use shared data control, and still don't want different instances of task flows to use same view object instances, then this post is for you.

Use case: Multiple instances of task flow should share same transaction context, however each UI should work independently when they are embedded in a parent page. As of now, there is no direct support for this. In this post I'm sharing a work around solution for this kind of scenario.

Solution: As I said earlier, this is just a work around solution, and intended to give you some idea on the implementation. Feel free to modify the code in the attached sample to meet your use cases.

Step 1. Edit the iterator used for for those pages fragments which needs to work independently, and alter binding for the view object instance used for this iterator to use an EL. EL takes the view object instance name from a PageFlow scoped variable.

 <iterator Binds="#{pageFlowScope.VOInstName}" RangeSize="25" DataControl="AppModuleDataControl" id="DepartmentsView1Iterator"/>  

Step 2. The PageFlow scoped variable that stores view object instance name used in the EL(step1 ) is populated from task flow initializer with some unique names. Task flow has a default method activity defined which will create corresponding view object instance in the Application Module before showing the page.

Download

You can download the sample workspace from here.
[Runs with Oracle JDeveloper 11.1.2.0.0 (11g R2) + HR Schema]

A glance at the implementation

Run main.jsf.
This page contains multiple instances of dept-task-flow-definition. However the page fragment used in each instances of task flow works independently using different view object instances eve though the dept-task-flow-definition has shared Data Control scope. This is done using the above idea. Take a look at TaskFlowDCHelper class to learn more about the implementation. Method TaskFlowDCHelper::initDataSource() generates the view object instance name for each instance and the same is set as initializer for dept-task-flow-definition. Method TaskFlowDCHelper::cleanupDataSource() is set as finalizer for task flow.

Comments

  1. Where do removeVO method execute?
    or ... How can i implemnent it? (when taskflow change i.e.)

    ReplyDelete
  2. One possible place could be taskflow finalizer

    ReplyDelete
  3. certainly, a very good post
    Thanks

    ReplyDelete
  4. I tried on 12c and got the following error: <ADF: Adding the following JSF error message: Object #{pageFlowScope.voInstName} of type View Object is not found.
    oracle.jbo.NoObjException: JBO-25003: Object #{pageFlowScope.voInstName} of type View Object is not found.

    I have double-checked that the pageFlowScope variable names that the bean puts the vo_name and vo_def_name are the same as the ones being passed to the am method binding.

    ReplyDelete
  5. AM,
    I could see the sample attached in the post working on 12.1.3.0.0. May be you can try the sample attached in the post and compare that with yours

    ReplyDelete
  6. Just downloaded and tried the sample. Weirdly for me on JDEVADF_12.1.2.0.0_GENERIC_130608.2330.6668 it seems the task flow instances don't seem to have their separate view object instances. When I change the department name from Shipping to Ship in one table and select another record, the new change reflects in all tables.

    ReplyDelete
  7. Oh OK. That behavior is expected because all the instances of the view objects in this example are based on same Entity Objects. so the changes would be reflected across all VO instances. This post discusses a use case where one may need to have different representation of same collection(based on different filtering logic), Not separating out the changes to individual VOs. In such case, you may really want to have isolated data control

    ReplyDelete
  8. Hello Jobinesh, thanks for the clarification. So, the query collection and row set remain the same for all vo instances, only that each tf has its own independent rowset iterator?

    ReplyDelete
  9. Yes, you are right !
    The blog post provides a work around solution for use cases where customer wanted to share same DC, but when used theses task flows in the UI multiple times, each one needs to work with its own collection instance.

    ReplyDelete

Post a Comment