Preventing refresh on MethodIterator in ADF 12c

On my current project I have a use case where a list of products needs to be retrieved. This is quite an expensive operation and could take a few seconds. Also, depending on the result I might have to remain on the same page and display an error message, or even skip the page displaying the list of products. This is a repeating process. As you can see below I have created a method call in between pages which does this orchestration. The method is being reused for all these steps.

Application flow

The logic in the method is quite straight forward. It simply executes a methodAction in the pageDefinition, and checks the result to see if the next screen needs to be skipped or not. It also handles errors.

Now at runtime I find that the method is actually being called twice and this is not desirable. After some digging I managed to exclude my code as the culprit. Even before the method is actually being called, the framework calls it for me. However when I navigate back and forth the method gets called only once (which is my method call at work).

So somehow ADF decides to be smart with me and execute the method. (probably because I have declared some variables in the same PageDef connected to this method)

Now in 11g it was quite easy to counter this behaviour. Just set the “Refresh”  property on the methodIterator to “never”. However in 12c this does not work. JDeveloper allows me to set it (using dropdown) but also immediately complains:

Error

Of course I ignored this message and tried to run it with no result. No errors, not warnings, however the method was still being called before I wanted it to. Also, it seems more of the values for the “Refresh” property are disallowed in 12c.  Crap…. what now?

After some more digging and experimenting I have found the refreshCondition to be helpful. The purpose of this value has always been more fine grained control over when iterators are being refreshed. For example, when your page contains an input parameter needed by the service to provide results, you would use the refreshCondition property to only allow the iterator to be refreshed after the parameter has been filled. (eg. refreshCondition=”#{bindings.inputParam.inputValue != null}”)

My solution was to have a boolean indicating whether the method was allowed to be refreshed in the pageflowScope. (any scope greater than request would probably do the trick).

Solution

Now in the methodAction I execute the method as follows:

this.refreshAllowed = true;
List errors = ADFUtils.executeMethodAction(NEXT_PAGE_METHOD, bindings);
this.refreshAllowed = false;

It is quite a nasty way to prevent the method from being called, but it works flawlessly now. Of course I would prefer to have an alternative like the Refresh=”never” setting in 11g. Any clues anyone?