19
votes

Is it possible to inject a request-scoped CDI bean into a Stateless session bean?

I had asked a related question and thought the specific CDI @RequestScoped into @Stateless question merited its own post.

Passing state between EJB methods / @RequestScoped and @Stateless

I also asked a similar question about JMS @MessageDriven beans - basically want to know the same about @Stateless.

@RequestScoped CDI injection into @MessageDriven bean

1
You could do, it's a proxy anyway, but does it conceptually make sense? Wouldn't you rather do it the other way round? That would end up in more natural and self-documenting code.BalusC
Fair point - even if it works, it would be hard to tell what was going on at first glance.wrschneider
@BalusC I was skeptical too, but lookup the CDI definition of request scoped. It's not just the http request scope, but also the scope that covers the request to an asynchronous method, remote method, mdb handling a msg, etc. So in that sense it is useful as a kind of replacement for TLS data.Mike Braun

1 Answers

34
votes

You can absolutely do what you mention and use @RequestScoped beans in an @Stateless session bean and an @MessageDriven bean. This is a core part of the CDI spec and TCK and guaranteed portable.

Note on MDBs

Do be aware that there is a test for a @Stateless bean that uses a @RequestScoped bean, but there is no test that guarantees a @MessageDriven bean can reference @RequestScoped beans. This was just an oversight and is already fixed for the Java EE 7 TCK. So just be aware that if it doesn't work for the MDB case, it may not be your fault :)

The workaround would be to simply have your MDB delegate to a SessionBean of any kind as @Stateless, @Stateful, and @Singleton all have @RequestScoped tests.

Making the EJB, itself, scoped

While @Stateless, @Singleton and @MessageDriven can have scoped references injected via @Inject, they cannot be @RequestScoped or any other scope. Only the @Stateful model is flexible enough to support scopes. In other words, you can annotate the @Stateful bean class itself as @RequestScoped, @SessionScoped, etc..

In simple terms @Stateless, @Singleton have fixed "scopes" already. @Singleton is essentially @ApplicationScoped and @Stateless would perhaps be some made-up scope like @InvocationScoped, if that existed. The lifecycle of an @MessageDriven bean is entirely up to the Connector that drives it and is therefore also not allowed to have user-defined scope.