我确实有一个 SessionScoped 类。对于每个用户访问,我需要一个自己的此类实例。很长一段时间一切都很好。但是现在我还需要在没有任何用户交互的情况下从后端访问这些对象。我确实有一个无状态企业 bean,但是每当我想访问会话范围的对象时,我都会得到一个异常。一个简单的示例代码如下:
@SessionScoped
public class SessionObj implements Serializable {
public String getValue() {
return "Hello World";
}
}
@Stateless
public class StatelessBean {
private static final Logger LOG=Logger.getLogger(StatelessBean.class);
@Inject
private SessionObj sessionObj;
public void test() {
LOG.info("session object: "+sessionObj);
LOG.info("Method call: "+sessionObj.getValue());
}
}
但是调用测试方法会以异常结束,例如:
12:19:10,484 ERROR [org.jboss.as.ejb3.tx.CMTTxInterceptor] (EJB default - 6) javax.ejb.EJBTransactionRolledbackException: WELD-001303 No active contexts for scope type javax.enterprise.context.SessionScoped
12:19:10,484 ERROR [org.jboss.ejb3.invocation] (EJB default - 6) JBAS014134: EJB Invocation failed on component StatelessBean for method public void package.StatelessBean.test(): javax.ejb.EJBTransactionRolledbackException: WELD-001303 No active contexts for scope type javax.enterprise.context.SessionScoped
at org.jboss.as.ejb3.tx.CMTTxInterceptor.handleInCallerTx(CMTTxInterceptor.java:139) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInCallerTx(CMTTxInterceptor.java:204) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
at org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:306) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:190) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]
...
Caused by: org.jboss.weld.context.ContextNotActiveException: WELD-001303 No active contexts for scope type javax.enterprise.context.SessionScoped
at org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:598) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:71) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:79) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
at package.SessionObj$Proxy$_$$_WeldClientProxy.toString(SessionObj$Proxy$_$$_WeldClientProxy.java) [ws_core_job_manager.jar:]
at java.lang.String.valueOf(String.java:2826) [rt.jar:1.6.0_21]
at java.lang.StringBuilder.append(StringBuilder.java:115) [rt.jar:1.6.0_21]
at package.StatelessBean.test(StatelessBean.java:29) [ws_core_job_manager.jar:]
...
所以我的问题是:* 即使没有会话,是否有任何选项可以通过任何技巧访问对象?* 是否有任何选项可以从我的无状态类中生成一个会话?
我了解异常的原因,但我想为现有代码的这种新用法设置一个“全局”会话。实际上,这当然不是那么容易,将会话范围的代码更改为 POJO 和会话范围的容器也不是那么容易。
环境:
- JDK 1.6
- JBOSS 7.1.1
解决方案:
正如 Jan 所说:扩展 StatelessBean 如下:
@Stateless
public class StatelessBean {
private static final Logger LOG=Logger.getLogger(StatelessBean.class);
@Inject
private BoundSessionContext sessionContext;
@Inject
private SessionObj sessionObj;
public void test() {
Map<String,Object> myMap=new HashMap<String,Object>();
sessionContext.associate(myMap);
sessionContext.activate();
LOG.info("session object: "+sessionObj);
LOG.info("Method call: "+sessionObj.getValue());
sessionContext.invalidate();
sessionContext.deactivate();
}
}
这个例子很有效!现在我只需要了解细节;-)