Easiest way of having ViewScope & avoiding LazyInitializationException on JBoss AS7 stack (JSF2, CDI, JPA2, Seam?)

StackOverflow https://stackoverflow.com/questions/10820683

Question

I am trying to set up a web application stack based upon JBoss AS7 for small-scale research prototypes and student projects that meets following requirements:

  1. I want to use AJAX-related scopes such as ViewScope -- or possibly a (View)AccessScope as in MyFaces Orchestra -- for my managed beans, in conjunction with PrimeFaces components.

  2. JPA-based persistence should be fairly straightforward, without having to deal with the OpenSessionInView pattern etc.. The main problem I am having with JPA2 is the dreaded LazyInitializationException, especially in AJAX calls. I do not require manual control over conversations.

  3. I want to use as few dependencies as possible, thus mostly relying on what is shipped with JBoss AS7.

Right now, I have set up a project with the following (mostly provided) Maven dependencies:

  • CDI
  • hibernate-2.0-api
  • jboss-ejb-api_3.1_spec
  • jboss-jsf-api_2.1_spec
  • jboss-annotations-api_1.1_spec
  • PrimeFaces 3

This looks pretty slim so far. What is missing is support for further JSF-specific scopes, and that I always get a LazyInitializationException when iterating over collections within a JSF page. Right now, my service classes for persistence look like this:

import javax.ejb.Stateful;
import javax.enterprise.context.RequestScoped;

@Stateful @RequestScoped
public class TestEntityService implements Serializable {
    @PersistenceContext(type=PersistenceContextType.EXTENDED)
    private EntityManager entityManager;

    // ... some methods working with the entityManager ...
}

And my ResourceFactory bean:

public class ResourceFactory {
    @Produces @PersistenceUnit
    private EntityManagerFactory entityManagerFactory;
}

I unsuccessfully tried combinations with @Named instead of @Stateful, or @SessionScoped instead of @RequestScoped. However, I found that adding the Seam 3 Persistence, Solder & Faces modules seems to cure most of my problems, but this adds a ton of new dependencies to my project (e.g. seam-security, prettyfaces, drools, joda-time and further dependencies).

My questions are:

  1. Would EJBs be of any help w.r.t. the LazyInitializationException? Or am I actually already using EJBs here due to the @Stateful annotation? I took this from a jboss-as sample application, but I am utterly confused by the differences between all these @ManagedBean, @Named, @Stateful, @LocalBean annotations... all I know is that I somehow need to bind the lifespan of my entity managers to the scope of the service bean.

  2. Does anybody know other easy ways of getting around this problem? Using EAGER fetching is not an option as this only seems to work if there is not more than one collection per entity...

  3. I just read about Apache CODI, which seems to be the CDI successor of MyFaces Orchestra. Is this a better alternative to Seam Faces? As far as I can see, it offers a ViewScope and ViewAccessScope, but nothing with regard to transaction management.

It would be great if someone with more experience in this field could shed some light on this -- I am currently a bit confused because there are so many libraries out there dealing with similar issues, albeit most apparently not compatible with each other (see e.g. here). Thanks!

Was it helpful?

Solution

You're right. All of this is quite confusing. This confusion comes from JSF2 and CDI providing the same feature. As these two specifications needs to work without the other they have similare annotations for Scope and EL exposition. This blog post details these confusing areas and how to make the right choice. To make it short, when using CDI with JSF, always use CDI annotations, or annotations that CDI will control thru an extension (as javax.faces.ViewScoped when you have Seam Faces or CODI in your project)

To answer to your questions

  1. You're already using EJB with @Stateful annotation. EJB won't help you directly with LazyInitializationException but they are more natural option to deal with transaction and database (you can't use @PersistenceContext annotation in a pojo CDI bean). Regarding the confusing annotations I already answered
  2. I have good experience with Seam Persistence. This CDI extension creates a managed Entity Manager that lives in conversation and allow the use of transaction outside EJB (if you don't have a Java EE container). Using this Entity Manager reduces significantly Lazy Lodaing issues. It can be inject in a stateless EJB which manage your DAO thanks to CDI magic that allows injecting Bean of different scope. Used in conjonction of Seam Faces you'll get the support of JSF ViewScope for CDI and a transaction tied to JSF lifecycle
  3. I don't have any experience with CODI which seems to bring useful functionalities like nested conversation.

In conclusion, be aware that Seam and CODI are in a merge process right now in Apache Delta Spike, so the solution you're about to build should be re-evaluated in the coming month to include Delta Spike in the equation.

OTHER TIPS

Honestly, there is no "one-size-fits-all" for CDI. Seam3 works great, MyFaces CODI works great, it really depends on what you want. For your situation, honestly, it seems like the easiest thing to do would be to create your own ViewScoped extension for your project, or pull the necessary parts from Seam 3 or CODI.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top