<h:form ...
<p:dataTable value="#{myBean.list}" var="data" ...
<p:column ...
<h:commandButton action="#{controller.method(data.id)}" />
</p:column>
</p:dataTable>
</h:form>
@ApplicationScoped
public class Controller {
public String method(final Long dataId) {
/* Do business */
return URL_WITH_REDIRECT;
}
}
(using the @ViewScoped CDI annotation as described here)
@ApplicationScoped
public class Producer {
@Named @ViewScoped @Producer
public MyBean getMyBean() {
final MyBean bean = new MyBean();
bean.list = new ArrayList<Data>(); // where Data has a Long id field
/* Do business and populate list */
return bean;
}
}
GET the page
POSTed to server@ViewScoped beans as expectedcontroller.method is called with data.id and accesses beans generated at 1.1
String
GET next page ...In short: on click, copy the id outside the datatable, and trigger a click on a submit button.
On the h:commandButton inside the table column added :
onclick="$('input[id*=selectedDataId]').val('#{data.id}'); $('button[id*=callMethod]').trigger('click');"
Outside the table:
<h:inputHidden id="{selectedDataId}"binding="#{selectedDataId}"/>
<p:commandButton type="submit"
id="callMethod"
label="Hidden button"
action="#{controller.method(selectedDataId.value)}"/>
At the end it works, but I was not able to figure out what causes the first & base approach to reinitialize the view scoped bean. Looking at the stack trace (see below) it seems like it is rebuilding the rows.
Does anyone have an explanation, and maybe caveats to look out for regarding this issue?
Where: getPipelinecheckSearchResults is the call for retrieving the list that backs the table, that causes the producer to be called

I've read following articles / SO questions without gaining any better understanding on why the above (1st) solution works as it does.
ViewScoped bean is recreated everytime I click on commandButton in my dataTable
Why does @PostConstruct callback fire every time even though bean is @ViewScoped? JSF
How can I pass selected row to commandLink inside dataTable?
http://balusc.blogspot.de/2010/06/benefits-and-pitfalls-of-viewscoped.html
https://java.net/jira/browse/JAVASERVERFACES-1492
I've found some sources for jsf/primefaces/ee-api/glassfish etc. to debug the behavior, so here's the answer:
component:controller.method) that causes redirect
datatable
datatable generates its rows based on a @ViewScoped beancontroller.method invocation the @ViewScoped bean that the datatable depends on will be regenerated (with all its dependencies of course)Tested: In version 2.1.7 of JSF.
Looked in sources of 2.1.19, and I'd expect same behavior there.
For those who cry out loud in lonely summer nights asking: "Why?"
POSTed to the serverAPPLICATION_INVOCATION
rowEvent & clickEvent
UIViewRoot:794
javax.faces.UIData The grandparent of org.primefaces.component.datatable.DataTable backing p:datatable starts processing the event @ UIData.broadcast(FacesEvent)
broadcast method first saves the index of the last selected rowrowEvent
clickEvent on the child UIComponent, in our case on the Button
ActionListener.processAction(ActionEvent)
controller.method which returns a redirect String and things begin to go downhillredirectString is processed by a NavigationHandler
ViewMap removing all @ViewScoped beans from it at line 179. Which if we think about it is kind of logical, since we're on our way out.UIData.broadcast which
302) 4.3.1
@ViewScoped bean(s) needed by the table get regenerated.THE END
Though I haven't tested I'd expect the same behavior h:datatable, p:accordionPanel, p:carousel, p:galleria, p:dataGrid etc. In short every component that subclasses UIData and doesn't provide a redirect - aware broadcast method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With