I have a @RequestScoped CDI bean that I want to turn into an EJB to get declarative transactions. (I’m on EJB 3.1, Java EE 6)
Currently, I am passing state between subroutines, under the assumption that the instance is only used in a single request. If I add @Stateless now that assumption would change.
For example, I want to do something like
@Stateless
@Named
@RequestScoped
public class Foo {
private String var1; // can't use instance vars in @Stateless?
private String var2;
public void transactionForRequest() {
var1 = value;
var2 = value;
....
subroutine();
}
}
I assume the above doesn’t work- is that correct?
I am contemplating two alternatives:
- Use @Stateful instead of @Stateless, along with @Named and @RequestScoped.
- Keep @Stateless and use
EJBContext.getContextDatamap to replace instance variables.
Which is better? And is there some other alternative I’m not thinking of? (Besides wait for Java EE 7 or switch to Spring. :-))
While
@Stateless,@Singletonand@MessageDrivencan have scoped references injected via@Inject, they cannot be@RequestScopedor any other scope. Only the@Statefulmodel is flexible enough to support scopes. In other words, you can annotate the@Statefulbean class itself as@RequestScoped,@SessionScoped, etc..In simple terms
@Stateless,@Singletonhave fixed “scopes” already.@Singletonis essentially@ApplicationScopedand@Statelesswould perhaps be some made-up scope like@InvocationScoped, if that existed. The lifecycle of an@MessageDrivenbean is entirely up to the Connector that drives it and is therefore also not allowed to have user-defined scope.See also https://stackoverflow.com/a/8720148/190816