I’m doing quite a lot of JSF demos and prototypes for my consulting and coaching engagements. So (some months ago) I started with a simple framework to speed up things.

One of the classes in this mini-framework is providing a query-by-example style user interaction

  • fill in a query form
  • perform a query based on the query fields
  • show a table with the query matches or show a form if a single row matched

For providing the query result I’m working with a DataModel that is implemented through a property model.

1
2
3
4
5
6
protected DataModel model = new ListDataModel(Collections.EMPTY_LIST);
@Override
public DataModel getModel() {
        model.setWrappedData(service.queryByExample(example));
        return model;
}

An instance of the class providing the property above is bound as a request scoped managed-bean. Everything is working fine, but as the JSF life-cycle allows a property to be read multiple times as the view is processed. In a simple GET request it would be called once only - during the RENDER_RESPONSE phase. In a post-back it would be called at least during APPLY_REQUEST_VALUES and RENDER_RESPONSE so the database would be hit at least twice. As I further analyzed this it got clear that the first hit is not returning the right result as the query form attributes have not yet been applied to the bound managed bean properties (this would only happen after the UPDATE_MODEL_VALUES phase). Only the second query execution returns the desired result.

So I was like this: why not suppress the first query make my database’s life not miserable. Using the beforePhase and afterPhase method binding of the <f:view> tag I managed to perform the query once only during the RENDER_RESPONSE phase. BUT now my command links for each row were not working anymore. What the heck is now going on… here you go. I had a conversation going with some folks from the myfaces/trinidad community. Today I also found a similar discussion going on in the Sun forum.