JPA lazy loading Collections in JSF view – better way than using Filters


Currently I am using a Transaction View pattern to make lazy-loading of collections possible in views.

I have the following in web.xml


And the Filter class has the following…

public class ViewFilter implements Filter {
  @Resource UserTransaction tx;

  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    try {
      chain.doFilter(request, response);
    //catch here
    finally {
      //another try-catch

Then assuming I have the following (rather contrived) backing bean

public class DepartmentEmployees {
  private DepartmentServiceBean deptService;
  private Integer deptId;
  private Department dept;

  public String init() {
    dept = deptService.findById(deptId);

I can do something like this in my view (.xhtml file)

<c:forEach var="emp" items="#{departmentEmployees.dept.employees}">
  <li>#{emp.firstName} #{emp.lastName}</li>

Just wondering if anybody knows of a different way to accomplish the same thing without using filters (or servlets).

Best Solution

This approach ("open session in view") has a couple of major disadvantages. Besides being kind of hacky (it's certainly not the design idea of a servlet filter to control a business session) you don't have many options to appropriately process any "real" exception that occurs while rendering the JSF page.

You don't write much about your infrastructure / technology stack, but I assume that you are on a Java EE 6 server.

I usually use the EntityManger in Extended Mode and flush it with transactions which I control explicitly by annotating only certain methods of my business facade. Have a look at this example (taken from Adam Bien - Real World Java EE Patterns, Rethinking Best Practices):

public class BookFacadeBean implements BookFacade {
    private EntityManager em;
    private Book currentBook;

    public Book find(long id){
        this.currentBook = this.em.find(Book.class, id);
        return this.currentBook;
    public void create(Book book){
        this.currentBook = book;
    public Book getCurrentBook() {
        return currentBook;
    public void save(){
        //nothing to do here

A next level in this approach would be to bind the EntityManager to a CDI conversation scope. Have a look at (a) Weld (b) Seam 3 Persistence for further discussions on that topic.

This is rather a rough sketch of an alternative than a detailed how-to. I hope this level of information is what you were asking about - feel free to ask further questions. :-)

Related Question