Showing posts with label ADF Data Controls. Show all posts
Showing posts with label ADF Data Controls. Show all posts

Tuesday, July 17, 2012

Refresh ADF table after a popup message/confirmation

In this blog post, I am demonstrating a way to refresh the contents of an ADF table after a certain action (any CRUD operation) especially when a confirmation popup or message has to be displayed.

Just creating an invokeAction on the binding to refresh the table works if there are no popups or message dialogs on button action. However, if you have a situation to refresh the table AND display the popup, you will just have to do an additional config. There could be other ways to solve this, but I found the following approach easy to work with.

The solution is to disable the 'cacheResults' property of the iterator to which the ADF table is bounded to and ensure that an "invokeAction" executable is created on the binding to refresh it (say prepareModel stage or renderModel stage for example). To do this,
  • Go to the page definition file and edit the source view
  • Find the iterator to which the ADF table is bounded with
  • Add the additional property cacheResults and set its value to false
<iterator Binds="AdminVO1" RangeSize="25" DataControl="AppModuleDataControl"
              id="AdminVO1Iterator" CacheResults="false"/>

Let us find out why this additional config is required? Why does the invokeAction which is set to re-execute on page render does not work when a popup/message is displayed?

By default, whenever an ADF table is created on a datacontrol it cache the results in memory in order to save on performance. Let us see what ADF documentation has to offer in this regard; (Highlighted portions that is of importance to this case)

When a data control modifies a collection, the data control must instantiate a new instance of the collection in order for the ADF Model layer to understand that it has been modified. In other words, although some action in the client may change the collection, that change will not be reflected in the UI unless a new instance of the collection is created. However, for performance reasons, accessor and method iterators cache their results set (by default, the cacheResults attribute on the iterator is set to true). This setting means that the iterator is refreshed and a new instance of the collection is created only when the page is first rendered. The iterator is not refreshed when the page is revisited, for example, if the page is refreshed using partial page rendering, or if the user navigates back to the page.

Since the popup/message dialog is displayed on action and the page refresh is interrupted midway, the refresh is not actually happening on just invokeAction and the table displays the cached results. However, if the iterator is set to not cache results, in a way we are forcing it to execute again for fetching the results when the page is rendered after the popup/message dialog display.

Thursday, July 12, 2012

ADF 11g WebService Data Control JBO-25080 and JBO-25058

I recently encountered a strange error while using a WebService Data Control on ADF. Since, I could not find any documentation or reference on this issue easily available on the web I thought of posting it here.

At runtime, the following error was logged in my console;

oracle.jbo.NoDefException: JBO-25080: Definition name: CancelRequest does not match the file in which it is loaded from: com.oracle.Requests.CancelRequest
at oracle.jbo.mom.DefinitionManager.loadLazyDefinitionObject(DefinitionManager.java:999)
at oracle.jbo.mom.DefinitionManager.loadParent(DefinitionManager.java:1228)
at oracle.jbo.mom.DefinitionManager.loadLazyDefinitionObject(DefinitionManager.java:933)
at oracle.jbo.mom.DefinitionManager.findDefinitionObject(DefinitionManager.java:482)
at oracle.jbo.mom.DefinitionManager.findDefinitionObjectDontCheckName(DefinitionManager.java:433)
at oracle.adf.model.bean.DCBeanDataControl.findStructureDef(DCBeanDataControl.java:1884)
at oracle.adf.model.bean.DCBeanDataControl.getAttributeDefs(DCBeanDataControl.java:1936)
...........................................................
...........................................................

Supplementing to the above error the following error was also logged;

oracle.security.jazn.JAZNRuntimeException: JBO-25058: Definition RequestId of type Attribute not found in RequestId

Even on repeated analysis (including the case sensitivity), everything seemed fine and the error message did not make sense.

After lots of googling around, I stumbled upon an Oracle forum where it noted a critical ADF bug.

"The package name CANNOT be the same as the class name". This will sound like a very ridiculous bug but that's the way it is at least for now (I am seeing this error in JDev 11.1.1.6). Since my class name and the package name were both 'CancelRequest', ADF data control went weird and complained with the JBO errors JBO-25080 & JBO-25058.

This can happen with EJB data controls as well!

I had to resolve the error the hard way. Had to go back and change my Web Service to reflect a different name (different name for the root node and operation). Operation name will be the package name and the parameter root element name will be thei class name when the WebService data control is generated.

Although you can do very little in a production scenario to handle this bug, you can probably take a different approach beforehand like using a WS Proxy or a POJO data control instead of a WebService data control if you see that the package name and class names are identical.