3
votes

Short story: I have a CDI @SessionScoped bean (annotation from javax.enterprise.context and not from javax.faces) called UserContextBean. I'd like to actually do something when an HTTP session is created.

So naturally I assumed that @PostConstruct would do the trick: get called only once when an instance of this bean is constructed. However, as per the documentation here, they say that the PostConstruct method is called :

When the managed bean is injected into a component, CDI calls the method after all injection has occurred and after all initializers have been called.

I had assumed that the post construct method would be called once, per session. However, practice is consistent with the documentation. This bean is injected into a @RequestScoped bean (also CDI) which serves as a backing bean for a JSF page and the PostConstruct method is called for every request.

I realize (now) that this is the behavior. But would there be any other way of doing a one time per session initialization?

Some code, although not very relevant:

@Named(UserContextBean.BEAN_NAME)
@SessionScoped
public class UserContextBean implements Serializable {

...

    @PostConstruct
    private void createSession() {
        System.out.println("UserContext created.");
    }
}

The request scoped bean where I inject this:

public abstract class WebPageDataProvider extends AbstractViewDataProvider {

    @Inject
    private UserContextBean userContext;

I was also thinking to use an HttpSessionListener and initialize the session bean, but it already sounds messy.

EDIT

Just noticed now that the HTTP session is not even created. If I create the session "manually", by calling getSession(true) (I do this inside a phase listener, for testing purposes, but only because it was already there) then everything works as expected.

1
How is your UI built? - John Ament
@JohnAment: Well, it's JSF 2 (Mojarra). The specific page I'm testing with is very simple. It's derived from a template and just brings together a couple of facelets. The EL expression that uses the request scoped bean is in the actual page, not in the facelets and just accesses a text property in the bean (which uses the user context bean to get a user role). - Marcel N.
Ok, good. Sorry, what about CDI implementation and container? If you're using tomcat, are you using CDI via servlet? - John Ament

1 Answers

0
votes

An HttpSessionListener is your best bet. What you could do is inject a SessionScoped component into the listener and set the value there.