Hi. Yes that is a new post about commandLink problem inside a dataTable: "CommandLink doesn't work!!!". But this one is different.
Ppl say "it works on other pages but not here" etc.. I'll show why.
There are millions of post about it in forums but i found no explanation why it happens. Everyone suggests using session scope beans, probably worst solution i have ever seen...
I'll explain the problem (not exacly a problem, i think) and hope great coders to find a better workaround.
Take a master-detail scenario. Using dataTable to list products and a commandLink to get details with ProductID as param.
listProducts.jsp
<h:dataTable id="products" value="#{ProductBean.allProducts}"
var="product">
<h:column>
<f:facet name="header">
<h:outputText value="ID" />
</f:facet>
<h:outputText value="#{product.product}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Name" />
</f:facet>
<h:outputText value="#{product.name}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="" />
</f:facet>
<h:commandLink value="View Details" immediate="true"
actionListener="#{Product.select}" action="detailProduct">
<f:param name="selectedID" value="#{product.id}" />
</h:commandLink>
</h:column>
</h:dataTable>
ProductBean - request scope:
public class ProductBean
{
public Collection getAllProducts()
{
// IMPORTANT!!
return GET_ALL_PRODUCTS_FROM_DATABASE;
}
}
in this scenario, when user clicks "View Details" commandLink,
JSF calls getAllProduct() by accessing ProductBean.allProducts background (to restore view maybe...) and commandLink
works.
So far everthing fine. But i.e. if I want to filter products, i cannot simply hardcode sql query to a getProducts() method (which datatable uses to list), because i need some criteria inputs. So suppose that i called findProdutsByName() before listing, then :
listFilteredProducts.jsp
<h:dataTable id="products" value="#{ProductBean.products}"
var="product">
<h:column>
<f:facet name="header">
<h:outputText value="ID" />
</f:facet>
<h:outputText value="#{product.product}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Name" />
</f:facet>
<h:outputText value="#{product.name}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="" />
</f:facet>
<h:commandLink value="View Details" immediate="true"
actionListener="#{Product.select}" action="detailProduct">
<f:param name="selectedID" value="#{product.id}" />
</h:commandLink>
</h:column>
</h:dataTable>
public class ProductBean
{
private Collection filteredProducts;
public Collection getAllProducts()
{
// IMPORTANT!!
return GET_ALL_PRODUCTS_FROM_DATABASE;
}
public Collection getProducts()
{
// IMPORTANT!!
// I know filteredProducts is not null, because I called findProductByName() in previous page
return filteredProducts;
}
}
in that case it will nicely list products again, but this time commandLink
will not work. Because when user clicks "View Details" commandLink, since ProductBean is request scope,
filteredProducts is null, so getProducts() returns null so commandLink does not works.
Thats why,
>> it works when bean set to session scope
i have tens of beans, i cant set all to session scope
> when <t:saveState> used
i'm not using myfaces..
http://forum.java.sun.com/thread.jspa?forumID=427&threadID=680962
So, this is by design.
So any other work arounds ?