Cannot @In(ject) a Stateful Session Bean into another Statef
jense007 Apr 18, 2007 10:05 AMHello,
we're evaluating SEAM 1.2.1 together with ICEfaces 1.6 Alpha and Facelets on GlassFish v2. It was easier than we thought, but we didn't manage to inject (or biject!) a stateful session bean into another.
What we want to do is the following:
- Have a "controller" bean for every window/tab @Scope(ScopeType.CONVERSATION) that holds information about currently selected item, navigation history etc.
- Have a "model" stateful session bean for storing available items for each view in use.
This way one could write the following expression
<h:outputText value="#{controller.selected.name}"/>
(Bean-Code is at the end of the posting...)
What happens is the following:
* The ControllerBean is created in Conversation-Context when used in the presentation layer.
* In NamingManagerImpl.java the following componentId is used as the namespace for lookup "MY_EAR_MY" (where "MY_EAR" is the (Eclipse) application-project and "MY" is the name of the web-application project)
* Note: this also works for the other component if used (and created) in the presentation layer (i.e. "model.getItems()")
* @In(jection) takes place, but of course there is no ModelBean in the session context
Now the Seam-Interceptor tries to auto-create a ModelBean, but when it comes to the lookup NamingManagerImpl retrieves the componentId relative to the ControllerBean
(using ComponentInvocation ci = im.getCurrentInvocation();)!
Thus it searches the namespace componentId "MY_EAR_MY_EJB.jar_ControllerBean_77129428636467201" which fails because there is no ModelBean component registered there.
But: If we change the componentId in the debugger manually to "MY_EAR_MY" everything works fine. Question is did we make a configuration error or is this a bug? We can't explain why direct creation works but @AutoCreate in another component does not. Any hints and help appreciated, thanks in advance!
Regards,
Jens
The whole application is EARed, consisting of a WAR, an EJB-Jar and an EJB-Client.jar, using Eclipse WTP 1.5.3 on Java 6 (and Java EE 5 of course).
// from web.xml <ejb-local-ref> <ejb-ref-name>ejb/ControllerBean/local</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <local>ControllerLocal</local> <ejb-link>MY_EJB.jar#ControllerBean</ejb-link> </ejb-local-ref> <!-- same for ModelBean -->
// ModelBean.java @Stateful @Name("model") @Scope(ScopeType.SESSION) @AutoCreate @Interceptors(SeamInterceptor.class) public class ModelBean implements ModelLocal, Serializable { ... }
// ControllerBean.java import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.Destroy; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Scope; import org.jboss.seam.ejb.SeamInterceptor; import java.io.Serializable; import java.util.*; import javax.ejb.Remove; import javax.ejb.Stateful; import javax.ejb.Stateless; import javax.interceptor.Interceptors; @Stateful @Name("controller") @Scope(ScopeType.CONVERSATION) @Interceptors(SeamInterceptor.class) public class ControllerBean implements ControllerLocal, Serializable { private static final long serialVersionUID = 9095028668253422692L; protected Item selected = null; protected ModelBusiness model; @Remove @Destroy public void remove_destroy() { } public ControllerBean() { if(model.getItems().size() > 0) { selected = model.getItems().get(0); } } // [...] @In //(create=true) // using @AutoCreate on ModelBean public void setModel(ModelBusiness model) { this.model = model; }