Hi,
 
Below are some thoughts that came to me after months of trying to understand the dataTable. Please verify that it is accurate enough for Wiki. 
 
1)    By definition the Restore-View phase should restores whatever that was being rendered in the Render-Response phase of the last request.
2)    A t:dataTable that does not persists its data in viewState would have to call the backing bean to obtain the table data again during the Restore-View phase. If the data obtained is different from what was being rendered previously, it could lead to inconsistencies.
3)    That explains tomahawk preserveDataModel="true" extension to dataTable component – to make ensure that (1) is upheld.
4)    Given the above understanding, consider the code scriplets below.
5)    preserveDataModel should be set to true base on the reasons given above. It will restores the backing bean dataModel using the setter method (*1), during the Restore-View phase.
6)    If the backing bean action changes the database, then the dataModel should be invalidated (*2) so that it will be regenerated with the updated data.
7)    However if the bean action is known to not doing any update to the database, the dataModel should be left alone.
8)    This pattern will avoid the most hated and hotly discussed problems of JSF hitting the database twice on every request. This pattern is actually highly optimal – in that it will only hit the database again when you explicitly invalidate the dataModel. The price to pay is relatively small – which is saving the page of data in the viewState.
 
------------------- The JSF --------------------------

      <t:dataTable id="table"

            …

        value="#{myBean.dataModel}"

        preserveDataModel="true">

 
------------------- The Backing Bean ------------------
 
public class myBean extends serializable {
 
(*2) public String changeDbAction() {
    // an action that changes the database. Invalidate the dataModel here
    // so that the it will be regenerated during the Render-Response phase
    this.dataModel = null; 
    …
    return SOME_NAVIGATION_RESULT;
}
 
(*3) public String doesNotChangeDbAction() {
    // action that does not change the database. So leaves the dataModel alone  
    // and the Render-Response phase will not result in hitting the database.
    …
    Return SOME_NAVIGATION_RESULT;
}

 

(*1) public setDataModel(DataModel d) {
    // t:dataTable will call this method to restore the table data
    this.dataModel = d;
}
 
    public DataModel getDataModel() {
        // if the dataModel is being invalidated then regenerates it again
        if (dataModel == null) {
            dataModel = new LocalDataModel(…);
        }
        return dataModel;
}

 

}

   

 

Best regards,

Yee

Reply via email to