jsfjakarta-eeejbstateful-session-bean

Using both @Stateful and @SessionScoped for shopping cart EJB


I know there's a lot of debate on using stateful vs stateless EJBs in web applications.

The shopping cart is the most common use case: Oracle's Java EE examples use it a lot in the official docs, too.

Here on stackoverflow I found many interesting answers like this The Shopping Cart dilemma in JavaEE which often say something like:

ok... SFSB are good in enterprise, complex scenarios, e.g. if you want to share them with other applications and make them available not only to JSF/web clients

but... if you're just developing your grandpa's e-commerce website, just stick to the HttpSession / SessionScoped cdi-managed bean, and write your business methods in SLSB, as they are more efficient, and so on...

However, because I'm still in a learning and discovery phase, I just want to give SFSB a try, by myself, trying to build a simple shopping cart.

I saw an interesting tutorial suggesting to store a JNDI-retrieved instance of the @Stateful shopping cart ejb interface in the HttpSession, the first time the web client needed it, then use it as usual, during the web session. In my JSF presentation layer, I suppose I would have a @SessionScoped @Named bean (let's call it ShopController), and, in its initialization, store one instance of the stateful ejb in an instance variable.

I wonder if it's possible to directly bind the @Stateful bean to the http session by annotating it with the @SessionScoped CDI annotation.

Will it work as described above? Will CDI create one SFSB for each web session?


Solution

  • @SessionScoped is for @Named beans and @Stateful is for @EJB beans. If I'm not wrong, you cannot annotate 1 bean with both. If you want to use @Stateful, just annotate your ShoppingCart bean with @EJB and @Local and then reference it in your ShopController. Something like this:

    @Named
    @SessionScoped
    public class ShopController {
        ...
        @EJB
        private ShoppingCart cart;
        ...
    
        // Getters and Setters
    }
    
    @Local
    @Stateful
    public class ShoppingCart {
        ...
    }