How and when should I load the model from database for JSF dataTable

Do it in bean’s @PostConstruct method.

@ManagedBean
@RequestScoped
public class Bean {

    private List<Item> items;

    @EJB
    private ItemService itemService;

    @PostConstruct
    public void init() {
        items = itemService.list();
    }

    public List<Item> getItems() {
        return items;
    }

}

And let the value reference the property (not method!).

<h:dataTable value="#{bean.items}" var="item">

In the @PostConstruct you have the advantage that it’s executed after construction and dependency injection. So in case that you’re using an EJB to do the DB interaction task, a @PostConstruct would definitely be the right place as injected dependencies would not be available inside a normal constructor yet. Moreover, when using a bean management framework which uses proxies, such as CDI @Named, the constructor may or may not be called the way you expect. It may be called multiple times during inspecting the class, generating the proxy, and/or creating the proxy.

At least do not perform the DB interaction job in the getter, unless it’s lazy loading and you really can’t do anything else. Namely, it would be invoked during every iteration round. Calling the service method during every iteration round is plain inefficient and may end up in “weird” side effects during presentation and postbacks, such as old values from DB seemingly still sticking around in the model instead of new submitted values.

If you rely on GET request parameters, then use <f:viewParam> and <f:viewAction> instead. See also Creating master-detail pages for entities, how to link them and which bean scope to choose.

If you want to preserve the model (the items property) across postbacks on the same view (e.g. CRUD table/dialog), then make the bean @ViewScoped, else the model won’t be in sync with the view when the same model is concurrently edited elsewhere. See also Creating master-detail table and dialog, how to reuse same dialog for create and edit.

If you utilize JPA’s @Version feature on the model, then you can catch OptimisticLockException to deal with it and show a message like “The data has been edited by someone else, please refresh/review if the desired changes are as intended”. See also Letting the presentation layer (JSF) handle business exceptions from service layer (EJB).

See also:

Leave a Comment