Model driven approach for building Dynamic UI
One of the great feature of ADF Rich Client is that support for building User Interfaces on the fly. These dynamic components are smart enough to read the binding metadata and render themselves on the fly. Please read this topic 22.7 Using a Dynamic Form to Determine Data to Display at Runtime, to learn more about this feature. When we talk about the dynamism provided by the ADF Rich Client, story is incomplete without referring support from the ADF BC (business service) layer. You can create dynamic EntityObject, ViewObject and wire them to UI components declaratively, without much effort. In this post, I'm discussing some common 'dynamic UI' based use case requirements and their solutions using ADF.
Case 1: Dynamic UI Table built using dynamic ViewObject(database table and attribute definitions change for each invocation)
Use case requirement: UI needs to be populated from different database tables, based on various business conditions. Number of displayed attributes may vary based on source database table.
Solution : Solution is pretty straight forward. Let us start from the business service layer and then move towards UI layer.
Business Service Layer
You can make use of ApplicationModule::createViewObjectFromQueryStmt(java.lang.String voName, java.lang.String sqlStatement) to define dynamic ViewObjects using the query supplied by the run time.
Binding Layer
Next step is to wire this dynamic ViewObject with UI. Define the necessary binding in your page definition file. You may need to do it manually as we are creating the ViewObject dynamically.
Sample page definition is shown below.
UI Layer
For building dynamic UI, either you can use <af:table> along with <af:foreach> to populate table on the fly, or simply leave the job to <dynamic:table> component. Let the component do the job for you. If you need to display the data in a dynamic parameter form, you can use <dynamic:form>
Dynamic components differ from standard components in that all the binding metadata is created at run time. This dynamic building of the bindings allows you set display information using control hints on a view object instead of configuring the information in the Edit Form Fields dialog as you drop the control onto the page
Table populated using <af:foreach> is shown below
Case 2: Dynamic UI Table built using ViewObject with dynamic query(Only database table changes, attribute definitions/column types may remain same)
Use case requirement: UI needs to be populated from different database tables, but attribute definition remains same. In other words, only the table changes, number of columns and types remain same.
Solution :
Business Service Layer
Here you just need to swap only the query part of the ViewObject. The attribute definitions remains same for all cases. You can use ViewObject::setQuery(java.lang.String query) to set Sets the user-defined query.
Building UI and the binding this with ViewObject remains same as for the normal implementation.
Case 3: Updatable Dynamic UI Table built using Dynamic EntityObject and ViewObject
Use case requirement: Needs to build an updatable UI based on the database table and attributes which are decided at run time.
Solution : This is a bit tricky situation. As the table is updatable, there should be an EntityObject to post the changes back to database.
Business Service Layer
Solution is to build EntityObject and corresponding ViewObject dynamically based on the metadata supplied by the run time.(Thanks to Steve who shared a sample on similar topic)
Below given sample code builds EntityObjects and corresponding ViewObject on the fly.
Binding Layer
'UI Wiring' part is same as discussed under Case 1.
UI Layer
Same as discussed under Case 1.
Conclusion
ADF offers a library of dynamic components which may help you to build dynamic UI without much effort. You may need to choose the right implementation strategy based on your use case requirement.
You can download the sample workspace from here.
[Runs with Oracle JDeveloper 11g R1 PS2 + HR Schema]
How to run this sample?
Run the main.jspx. Main page display menu(link) for each case that we discussed here. You can select Department/Employee from the drop down list and then opt for one of the three cases by clicking the corresponding links. This takes you to a result page where data is rendered in a tabular form. This UI is generated on the fly based on the item selected from the drop down.
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
Case 1: Dynamic UI Table built using dynamic ViewObject(database table and attribute definitions change for each invocation)
Use case requirement: UI needs to be populated from different database tables, based on various business conditions. Number of displayed attributes may vary based on source database table.
Solution : Solution is pretty straight forward. Let us start from the business service layer and then move towards UI layer.
Business Service Layer
You can make use of ApplicationModule::createViewObjectFromQueryStmt(java.lang.String voName, java.lang.String sqlStatement) to define dynamic ViewObjects using the query supplied by the run time.
Binding Layer
Next step is to wire this dynamic ViewObject with UI. Define the necessary binding in your page definition file. You may need to do it manually as we are creating the ViewObject dynamically.
Sample page definition is shown below.
<executables>
<variableIterator id="variables"/>
<iterator Binds="DynamicQueryVO" DataControl="AppModuleDataControl"
id="DynamicVOIterator"/>
</executables>
<bindings>
<tree IterBinding="DynamicVOIterator" id="DynamicVO">
<nodeDefinition Name="Dummy"></nodeDefinition>
</tree>
</bindings>
UI Layer
For building dynamic UI, either you can use <af:table> along with <af:foreach> to populate table on the fly, or simply leave the job to <dynamic:table> component. Let the component do the job for you. If you need to display the data in a dynamic parameter form, you can use <dynamic:form>
Dynamic components differ from standard components in that all the binding metadata is created at run time. This dynamic building of the bindings allows you set display information using control hints on a view object instead of configuring the information in the Edit Form Fields dialog as you drop the control onto the page
Table populated using <af:foreach> is shown below
<af:table rows="#{bindings.DynamicVO.rangeSize}"
fetchSize="#{bindings.DynamicVO.rangeSize}"
emptyText="#{bindings.DynamicVO.viewable ? 'No data to display.' : 'Access Denied.'}"
var="row" rowBandingInterval="0"
value="#{bindings.DynamicVO.collectionModel}"
selectedRowKeys="#{bindings.DynamicVO.collectionModel.selectedRow}"
selectionListener="#{bindings.DynamicVO.collectionModel.makeCurrent}"
rowSelection="single" id="t1">
<af:forEach items="#{bindings.DynamicVOIterator.attributeDefs}"
var="def">
<af:column headerText="#{def.name}" sortable="true"
sortProperty="#{def.name}" id="c1">
<af:outputText value="#{row[def.name]}" id="ot1"/>
</af:column>
</af:forEach>
</af:table>
Using dynamic:table to display dynamic contents is shown below.<dynamic:table value="#{bindings.DynamicVOIterator}" id="t3"/>
Case 2: Dynamic UI Table built using ViewObject with dynamic query(Only database table changes, attribute definitions/column types may remain same)
Use case requirement: UI needs to be populated from different database tables, but attribute definition remains same. In other words, only the table changes, number of columns and types remain same.
Solution :
Business Service Layer
Here you just need to swap only the query part of the ViewObject. The attribute definitions remains same for all cases. You can use ViewObject::setQuery(java.lang.String query) to set Sets the user-defined query.
Building UI and the binding this with ViewObject remains same as for the normal implementation.
Case 3: Updatable Dynamic UI Table built using Dynamic EntityObject and ViewObject
Use case requirement: Needs to build an updatable UI based on the database table and attributes which are decided at run time.
Solution : This is a bit tricky situation. As the table is updatable, there should be an EntityObject to post the changes back to database.
Business Service Layer
Solution is to build EntityObject and corresponding ViewObject dynamically based on the metadata supplied by the run time.(Thanks to Steve who shared a sample on similar topic)
Below given sample code builds EntityObjects and corresponding ViewObject on the fly.
EntityDefImpl newEntity = new EntityDefImpl(DYNAMIC_EO);
newEntity.setSource("EMPLOYEES");
AttributeDefImpl newAttrDef1 =
newEntity.addAttribute("EmployeeId", "EMPLOYEE_ID", Number.class,
true, false, true);
ViewDefImpl newView = new ViewDefImpl(DYNAMIC_VO);
newView.addEntityUsage("e", DYNAMIC_EO, false, false);
newView.addAllEntityAttributes("e");
newView.setFetchSize((short)30);
newView.setSelectClauseFlags(ViewDefImpl.CLAUSE_GENERATE_RT);
newView.setWhereClauseFlags(ViewDefImpl.CLAUSE_GENERATE_RT);
newView.setFromClauseFlags(ViewDefImpl.CLAUSE_GENERATE_RT);
newView.resolveDefObject();
newView.registerDefObject();
Binding Layer
'UI Wiring' part is same as discussed under Case 1.
UI Layer
Same as discussed under Case 1.
Conclusion
ADF offers a library of dynamic components which may help you to build dynamic UI without much effort. You may need to choose the right implementation strategy based on your use case requirement.
You can download the sample workspace from here.
[Runs with Oracle JDeveloper 11g R1 PS2 + HR Schema]
How to run this sample?
Run the main.jspx. Main page display menu(link) for each case that we discussed here. You can select Department/Employee from the drop down list and then opt for one of the three cases by clicking the corresponding links. This takes you to a result page where data is rendered in a tabular form. This UI is generated on the fly based on the item selected from the drop down.
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
Its a very nice post indeed and a real-time scenario. Thank you, but some problems in the UI part I think, as I am getting error with the sample,
ReplyDeleteADF: Adding the following JSF error message: ORA-00942: table or view does not exist
java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist
I just ran as written on the blog.
Shankar,
ReplyDeleteYou may need to have HR schema (sample schema comes along with Oracle DB) installed in your DB/ Or change the 'Connection' to reflect your local settings
I got it working for my app thanks a lot.
ReplyDeleteVery good example for creating dynamic view objects.
Can I link to dynamic view objects having transient attributes as primary keys ?
Shankar,
ReplyDeleteTheoretically answer is Yes. Personally I've not noticed such use-cases before.
Thanks for this post. I am able to create a dynamic EO and dynamic VO based on this dynamic EO.
ReplyDeleteThis works fine. But when I am testing my application for the passivation safe I am getting NullPointer error when AM is activating. Do we need to handle such VO in special way?
oracle.jbo.JboException: JBO-29000: Unexpected exception caught: java.lang.NullPointerException, msg=null
at oracle.jbo.server.Serializer.activate(Serializer.java:304)
at oracle.jbo.server.DBSerializer.activateRootAM(DBSerializer.java:327)
at oracle.jbo.server.ApplicationModuleImpl.activateState(ApplicationModuleImpl.java:5959)
at oracle.jbo.server.ApplicationPoolMessageHandler.doPoolMessage(ApplicationPoolMessageHandler.java:210)
at oracle.jbo.server.ApplicationModuleImpl.doPoolMessage(ApplicationModuleImpl.java:8651)
at oracle.jbo.common.ampool.ApplicationPoolImpl.sendPoolMessage(ApplicationPoolImpl.java:4405)
at oracle.jbo.common.ampool.ApplicationPoolImpl.prepareApplicationModule(ApplicationPoolImpl.java:2391)
at oracle.jbo.common.ampool.ApplicationPoolImpl.doCheckout(ApplicationPoolImpl.java:2203)
at oracle.jbo.common.ampool.ApplicationPoolImpl.useApplicationModule(ApplicationPoolImpl.java:3101)
at oracle.jbo.common.ampool.SessionCookieImpl.useApplicationModule(SessionCookieImpl.java:460)
at oracle.jbo.http.HttpSessionCookieImpl.useApplicationModule(HttpSessionCookieImpl.java:234)
at oracle.jbo.common.ampool.SessionCookieImpl.useApplicationModule(SessionCookieImpl.java:431)
at oracle.jbo.common.ampool.SessionCookieImpl.useApplicationModule(SessionCookieImpl.java:426)
at oracle.adf.model.bc4j.DCJboDataControl.initializeApplicationModule(DCJboDataControl.java:512)
at oracle.adf.model.bc4j.DCJboDataControl.getApplicationModule(DCJboDataControl.java:855)
at oracle.adf.model.binding.DCBindingContainer.findDataControl(DCBindingContainer.java:1616)
at oracle.jbo.uicli.binding.JUCtrlActionBinding.getDataControl(JUCtrlActionBinding.java:556)
at oracle.jbo.uicli.binding.JUCtrlActionBinding.invoke(JUCtrlActionBinding.java:728)
Is there something which I will be missing?
There was a product bug#9271129 (fixed in internal builds) with similar symptoms. You may be able to uptake the fix with next immediate release.
ReplyDeleteHi Jobnish,
ReplyDeleteThanks for the bug no. but when I try to check this bug number using support.oracle.com. I am not able to view the details.
Just wanted to confirm the details of the bug.
I was just thinking (though didn't try yet) can we create a dummy eo and vo and then at the runtime define the definition of eo and vo in there definition classes will solve this problem or not. The only problem I can see is that since in my case the eo and vo has xml files it will try to load the eo and vo based on the eo.xml or vo.xml file instead of my runtime definition. Please suggest.
Hi Jobinesh,
ReplyDeleteI tried created case 2 in the model driven approach to building dynamic ui.
First i created a DynamicInvTable1 view object with a bind variable
"select ji.invoice_id from invoices ji where ji.invoice_number= :selectInvoiceNumber"
Then in the AM, i try to dynamically set it to a new query with the same attributes
query = "select ji.invoice_id from invoices ji ,jobs ii where ji.invoice_id = ii.invoice_id"
I follow it up in the AM
ViewObjectImpl vo = (ViewObjectImpl)findViewObject("DynamicInvTable1");
vo.setFullSqlMode(vo.FULLSQL_MODE_AUGMENTATION);
vo.setQuery(query);
vo.executeQuery();
but i get the error
"ADF: Adding the following JSF error message: Attempt to set a parameter name that does not occur in the SQL: selectInvoiceNumber
java.sql.SQLException: Attempt to set a parameter name that does not occur in the SQL: selectInvoiceNumber"
Should it not "forget" the previous query ?
Any idea why this is happening ?
Sunil,
ReplyDeleteYou may need to try removing the bind variable before modifying the query. ViewObjectImpl::ensureVariableManager().removeVariable(name)
Hi Jobinesh,
ReplyDeleteThanx for a great sample - but I keep getting an this error - when I try to switch from Employee to Department in Usecase #3
Server Exception during PPR, #1
javax.el.PropertyNotFoundException: Target Unreachable, 'DepartmentId' returned null
at com.sun.el.parser.AstValue.getTarget(AstValue.java:88)
at com.sun.el.parser.AstValue.isReadOnly(AstValue.java:126)
at com.sun.el.ValueExpressionImpl.isReadOnly(ValueExpressionImpl.java:230)
at oracle.adfinternal.view.faces.renderkit.rich.EditableValueRenderer._getUncachedReadOnly(EditableValueRenderer.java:483)
at oracle.adfinternal.view.faces.renderkit.rich.EditableValueRenderer.cacheReadOnly(EditableValueRenderer.java:413)
at oracle.adfinternal.view.faces.renderkit.rich.LabeledInputRenderer.beforeEncode(LabeledInputRenderer.java:116)
Removed the rest of the logging....
Thanks, Henrik
Henrik,
ReplyDeleteI'm sorry, look like you hit this bug#10028224. This is fixed in the internal builds.
Nice post, thanks.
ReplyDeleteBut when I run the sample with unchecked "Enable Application Module Pooling" in AM settings I keep receiving strange error:
<_handleException> ADF_FACES-60098:Faces - cykl życia otrzymuje nieobsługiwane wyjątki w fazie APPLY_REQUEST_VALUES 2
javax.el.PropertyNotFoundException: Target Unreachable, 'DynamicForm_dynamic_VO_f2' returned null
at com.sun.el.parser.AstValue.getTarget(Unknown Source)
at com.sun.el.parser.AstValue.isReadOnly(Unknown Source)
at com.sun.el.ValueExpressionImpl.isReadOnly(Unknown Source)
at oracle.adfinternal.view.faces.renderkit.rich.EditableValueRenderer._getUncachedReadOnly(EditableValueRenderer.java:486)
at oracle.adfinternal.view.faces.renderkit.rich.EditableValueRenderer.getReadOnly(EditableValueRenderer.java:400)
at oracle.adfinternal.view.faces.renderkit.rich.EditableValueRenderer.wasSubmitted(EditableValueRenderer.java:343)
at oracle.adfinternal.view.faces.renderkit.rich.EditableValueRenderer.decodeInternal(EditableValueRenderer.java:116)
at oracle.adfinternal.view.faces.renderkit.rich.LabeledInputRenderer.decodeInternal(LabeledInputRenderer.java:56)
at oracle.adf.view.rich.render.RichRenderer.decode(RichRenderer.java:293)
I tried with new ADF 11.1.1.4.0 and error still occurs.
Can you check if 11.1.1.4.0 contains fix for bug#10028224?
Do you know any workarounds?
thanks,
Miroslaw
Miroslaw,
ReplyDeleteThanks for pointing it out.However,I'm not able to reproduce it when I tried my sample(attached with the post) on the build you mentioned. Can you please help me by detailing the steps needs to followed( assuming the issue is reproducible on my sample) for reproducing the error you mentioned.
Thanks
A little mistake: I have used sample workspace from your another great post (Enabling LOVs for Dynamic ViewObject attributes - file DynamicUIWithLOV.zip).
ReplyDeleteReproducing is simple:
- uncheck AM pooling,
- run sample,
- go to Departments,
- click "Take me back"
and error should occur.
thanks,
Miroslaw
Hi Jobinesh,
ReplyDeleteThis is nice one. but i want to generate the UI component also dynamically. for eg:- instead of output text for all the columns in a grid, for some column i want to display it as boolean check box.is it possible.
Bhagki.
Bhagki,
ReplyDeleteYou can give a try using dynamic:table + Dynamic VO with proper cntrl hints, personally I've never tried though.
I am Alexandr.
ReplyDeleteGood blog;
Issue.
Can I dynamically create the ViewObject from xml?
1. Create the ViewObject Wizard Jdeveloper.
2. Post the xml to another ApplicationModuleImpl
3. Get access to it.
Alexandr,
ReplyDeleteCan you please detail the use case. Is this Desing Time(development phase) requirement? Are you looking for some automated VO generation mechanism as part of build process. If not, the example in the blog for generating VO at run time holds good for you.
Alexsandr
ReplyDeletexml more.
For example set Control Hints
set
< PropertiesBundle
in Label text or set the column name.
(I want to apply your example for ADF Swing Desctop ... with dynamic xml i have finished screen forms and JTable)
Hi Jobinesh
ReplyDeleteNice Post. Just going thru it as Im a adf newbie. While debugging I found that the Lifecyle phase doesnt consider the overriden preparerenderer method in the page controller - DynamicBindingEnabledPageController.
please correct me if I shouldnt expect it to fire the prepare renderr method. I also added some debug statements (sops) before super was called and nothing seems to get printed in the logs. I am expecting the preparerenderer method to fire before a page is rendered. will be nice to hear from you. thanks
I'm not using DynamicBindingEnabledPageController in the sample(not added to pageDefinition file as a ControllerClass). A custom page controller is required if you have page which posts request to itself and changes underlying VO while processing the request.In other words an action changes underlying VO used by the binding and displays modified 'view' - Here ControllerClass can be used to clear the previous binding before displaying new comp. tree bound to the updated VO defn.
ReplyDeleteHi Jobinesh,
ReplyDeleteI need to create a dynamic table based on arraylist. As mentioned by you I used for doin this. To the table added a binding too. From the binding setter i'm calling createdynamictable() method which take cares of creating a table programmatically. This is working fine indiviually. Now I addef two SOC on the page. After selecting the value from the first list it again calls the createdynamictable() method which leads to null pointer. I think the collectionModel is the reason for the complete page refresh on performing some other action. So I removed the table binding and added the createdynamictable() method call to getCollectiomModel(). Now the SOC is working fine and not leading to the null pointer. But the table is not being created. Can you please suggest a solution in which both the table and SOC would work fine..
Thanks
Nita
Nita
ReplyDeleteIf you can share a sample, I'll take a look
Thanks alot... I have shared the code on
ReplyDeletehttps://forums.oracle.com/forums/message.jspa?messageID=10295643#10295643
Hi,
ReplyDeleteHelpful post, thanks.
I have an issue with af:forEach with VO from query stmt.
My page def is similar to yours. At run-time ADF Dynamic Table (forEach) displays empty rows.
If there are 10 results(rows) for the query, I see 10 empty rows with a single column. Column doesn't have header either.
Binding
-------
<bindings>
<tree IterBinding="DynamicVO1Iterator" id="DynamicVO1">
<nodeDefinition Name="Dummy"></nodeDefinition>
</tree>
Page
----
<af:table rows="#{bindings.DynamicVO1.rangeSize}"
fetchSize="#{bindings.DynamicVO1.rangeSize}"
emptyText="#{bindings.DynamicVO1.viewable ? 'No data to display.' : 'Access Denied.'}"
var="row"
value="#{bindings.DynamicVO1.collectionModel}"
selectedRowKeys="#{bindings.DynamicVO1.collectionModel.selectedRow}"
selectionListener="#{bindings.DynamicVO1.collectionModel.makeCurrent}"
rowSelection="single" id="t1" styleClass="AFStretchWidth"
columnStretching="blank" autoHeightRows="24"
contentDelivery="immediate">
<af:column minimumWidth="10" width="10" rowHeader="true" id="c2"/>
<af:forEach items="#{bindings.DynamicVO1.attributeDefs}"
var="def">
<af:column headerText="#{bindings.DynamicVO1.labels[def.name]}"
sortable="true" sortProperty="#{def.name}" id="c1">
<af:outputText value="#{row[def.name]}" id="ot1"/>
</af:column>
</af:forEach>
</af:table>
This comment has been removed by the author.
ReplyDeleteNice Article, Jibonesh.
ReplyDeleteI have a requirement where we have to define the layout in a UI(which is stored in a database) for labels and corresponding fields for a form so that they can be loaded dynamically when the page renders.
Any suggestions on how to do it?
Bibs
ReplyDeleteADF Faces support dynamic:form for this
Thanks Jobonesh.
ReplyDeleteDo you have any article or any link to look more into dynamic:form?
Thanks
Bibhu
Hi! Can You please say what I need to do to insert new row in USE CASE 3?
ReplyDeleteBest regards, Kristaps
Any idea?
ReplyDeleteClient side usage is like normal VO/EO. EO will have logic to push updated data to custom data store by overriding doDML()
ReplyDeleteHi Jobinesh,
ReplyDeleteVery nice post. Thanks.
But,not getting an idea incase we need to create multiple dynamic tables on a page!!
Like we are getting the data in object form and based on that "n" tables would be getting created at run time!!
Eaiear solution is to embed this logic in a task flow and use multi task flow approach for embedding them on a page at rurimr
ReplyDeleteEaiear solution is to embed this logic in a task flow and use multi task flow approach for embedding them on a page at rurimr
ReplyDeleteNice Blog and Posts. Many thanks.
ReplyDeleteI have a requirement as in Case 1(Dynamic UI Table built using dynamic ViewObject(database table and attribute definitions change for each invocation))
So I have followed steps listed for Case1.
My page is like
--Input Text Box---
--Link---
===Dynamic Table(using af:foreach)===
When user clicks the link, dynamic table details are displayed according to input text.
So, what I have done is make rendered attribute of 'Dynamic Table' initially false .
When user clicks the link(action listener is ), call AM method (passing query stmt)which does createViewObjectFromQueryStmt,
then make rendered true for dynamic table.
Every thing is working fine, but when page loads I get error popup
Object DynamicQueryVO of type View Object is not found.
Same pop up comes when link is clicked.
Stack trace of the error popup :
ADF: Adding the following JSF error message: Object DynamicQueryVO of type View Object is not found.
oracle.jbo.NoObjException: JBO-25003: Object DynamicQueryVO of type View Object is not found.
at oracle.adf.model.binding.DCIteratorBinding.getViewObject(DCIteratorBinding.java:1520)
at oracle.adf.model.binding.DCIteratorBinding.getViewObject(DCIteratorBinding.java:1360)
at oracle.adf.model.binding.DCIteratorBinding.initSourceRSI(DCIteratorBinding.java:1722)
at oracle.adf.model.binding.DCIteratorBinding.callInitSourceRSI(DCIteratorBinding.java:1672)
at oracle.adf.model.binding.DCIteratorBinding.internalGetRowSetIterator(DCIteratorBinding.java:1645)
at oracle.adf.model.binding.DCIteratorBinding.refresh(DCIteratorBinding.java:4358)
at oracle.adf.model.binding.DCExecutableBinding.refreshIfNeeded(DCExecutableBinding.java:341)
at oracle.adf.model.binding.DCIteratorBinding.getAttributeDefs(DCIteratorBinding.java:3140)
at oracle.adf.model.binding.DCIteratorBinding.getAttributeDefs(DCIteratorBinding.java:3133)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at oracle.jbo.common.JboBeanUtils.getProperty(JboBeanUtils.java:113)
at oracle.jbo.common.JboAbstractMap.internalGet(JboAbstractMap.java:97)
at oracle.adf.model.binding.DCExecutableBinding.internalGet(DCExecutableBinding.java:169)
at oracle.adf.model.binding.DCIteratorBinding.internalGet(DCIteratorBinding.java:4571)
at oracle.adf.model.binding.DCExecutableBinding.get(DCExecutableBinding.java:115)
at javax.el.MapELResolver.getValue(MapELResolver.java:164)
Here, should I need to create a proxy VO and replace it in run time ?will proxy VO works if database table and attribute definitions change for each invocation?
Could you please help in knowing why I get that error popup and how to resolve it
Many Thanks
Hi Jobinesh,
ReplyDeleteI have to generate the UI components in the table dynamically.I have boolean check box in the table.
As you said in the blog i dont know about much about control hints.
But i tried in this way..
it is displaying good in the UI whatever values from the dab..But problem is It is showing as 'READ_ONLY' ..am not able to update selectBox...Is ther any properties do need to set it to became updatable...Thanks
Hi Jobinesh,
ReplyDeletePlease confirm if Case# 3 holds valid to create a dynamic editable form?
Best Regards,
Ankit Gupta
This comment has been removed by the author.
ReplyDeleteHi Jobinesh,
ReplyDeletevery helpful post.
I have one question concerning entity cache. In your example you are using this technique to remove the view and clear the cache:
internalDynamicVO.remove();
getDBTransaction().clearEntityCache(DYNAMIC_EO);
removeEntityCacheByDefName(DYNAMIC_EO);
getTransaction().rollback();
so why do you clear the cache at all if it is removed in the next line? Is this necessary? In my case it is causing:
JBO-25303: Cannot clear entity cache dynamic.EO because it has modified rows
on dbTrans.clearEntityCache(DYNAMIC_EO) when I want to reset the view object.
The problem is solved when I call
removeEntityCacheByDefName(DYNAMIC_EO);
before
dbTrans.clearEntityCache(DYNAMIC_EO);
Is this ok?
łukaszG
ReplyDeleteThanks for pointing it out.
Alternatively, you can try calling getTransaction().rollback(); as first statement before clearing cache. As you pointed out there is redundant call in my code- sorry for that.So either of the below will work
getTransaction().rollback();
getDBTransaction().clearEntityCache(DYNAMIC_EO);
or
the way you tried - no need to call
getDBTransaction().clearEntityCache(DYNAMIC_EO); in that case.
btw, you can take a look at some new samples as well which make use of some 12 C features http://www.jobinesh.com/2013/08/building-dynamic-ui-using.html
Hi Jobinesh,
ReplyDeleteTo create an editable dynamic form, I used the similar approach and wired the "value" property of input text field to "#bindings[def.name].inputValue}", however during form render, no value is shown.
Please advise if additional steps are required to achieve the same.
Best Regards,
Ankit Gupta
Hi Jobinesh,
ReplyDeleteNice Article, Do you know if this approach is safe on a multiuser enviroment? Because the view definition and view instance are created with the same name. Could two users at the same time , view the view object definition created on another user session?
Thanks
Hi Jobinesh
ReplyDeleteThis is really a very good article and solved most of my issues at hand.
I downloaded the sample and ran it and it runs well.
I tried to replicate it and my adf read only dynamic table does not let me sort it. It says that the attribute (which I am trying to sort) is not found in the DynamicVO.
I tried to find what the issue might be but could not find it.
Only difference between your demo and my application is that the string that I pass for dynamic VO creation(input text) and the table itself is on the same page.
So for the dynamic vo to work , I have a default activity in my taskflow which creates the dynamic VO from "Select * from dual" query. Then when the user has entered the actual query on the page, I create the VO again with that query.
Any pointers as to why I am getting oracle.jbo.NoDefException: JBO-25058 and your sample app does not?