5
votes

I'd like to inject a sessionscoped CDI bean into a stateless EJB. At access time of the EJB the correct instance of the sessionscoped cdi bean (i.e. the one in the sessionscope of the caller) should be used. I know that I can solve this with a stateful EJB, however I'd really like to know if this is solvable with CDI also. As the EJB and the Servlet run in the same war I'd assume they share the same thread and the container should be able to figure out the correct sessionscoped bean in the EJB?

For example:

EJB:

@Stateless
@LocalBean
public class StatelessSessionBean {

    @Inject    
    Instance<SessionData> sessionData;    

    public String testMethod() {
        SessionData bean = sessionData.get();
        String result = "Retrieved bean " + bean + " with UUID "+ bean.uuid + ". Created on: " + new SimpleDateFormat("dd.MM.yyyy HH:mm").format(bean.creationDate);
        return result;
    }
}

CDI Bean:

@SessionScoped
public class SessionData implements Serializable {      

    String uuid;
    Date creationDate;

    public SessionData() {
        uuid = UUID.randomUUID().toString();
        creationDate = new Date();
    }    
}

When I now access the stateless EJB e.g. from a servlet, I'd like testMethod to use the CDI bean which is associated with the caller's HTTPSession. So if two clients from different browser/http sessions access the Servlet they should both get different result strings.

Do I need a CDI Provider instead of the Instance and if yes how do I produce the correct instance of the bean for the given session? I thought about maybe getting the BeanManager and searching for instances of the SessionData but I don't know how I'd get the correct one.

Any help is greatly appreciated, thanks !

2
You didn't tell what happened when you tried your code. - JB Nizet
What application server or CDI implementation are you using? I recommend adding a tag. - Brett Kail
@bkail I'm using glasfish 4 and afaik this is weld... I added the tags - Korgen
@JBNizet I have to be more specific: I get back a different reference, but with the same UUID always and the same creation date... so I think the proxy is different but the used object is the same - Korgen

2 Answers

5
votes

Ok, now I feel kind of stupid :-(

I was bypassing the contextual bean provided by the proxy by not-using getters/setters for the member access. Instead I directly used the package-private fields which prevents the proxy from providing the right instance.

As soon as I switched to getters/setters it started working as expected.

0
votes

Injection of long-lived bean scopes into short-lived ones (including the Dependent scope for EJBs) works out of the box thanks to client proxies.

See also the corresponding section in the Weld reference manual.