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;
}