java 从无状态 EJB 访问 SessionScoped 对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11521613/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 05:25:09  来源:igfitidea点击:

Access SessionScoped object from stateless EJB

javajakarta-eecdi

提问by Martin Metz

I do have a SessionScoped class. For each user access I need an own instance of this class. All went fine for a long time. But now I also need access to this objects from the backend without any user interaction. I do have a stateless enterprise bean but whenever I want to access the session scoped object I get an excepiton. A simple example code is as following:

我确实有一个 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());
    }

}

But calling the test method ends in an exception like:

但是调用测试方法以如下异常结束:

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:]
    ...

So my question is: * Is there any option to access the object even without a session by any trick? * Is there any option to generate one session from within my stateless class?

所以我的问题是: * 是否有任何选项可以通过任何技巧在没有会话的情况下访问对象?* 是否有任何选项可以从我的无状态类中生成一个会话?

I understand the cause of the exception but I want to have one 'global' session for this new usage of the existing code. In reallity of course it's not so easy and changing the session scoped code to a POJO and a session scoped container is not so easy.

我了解异常的原因,但我想为现有代码的这种新用法设置一个“全局”会话。实际上,这当然不是那么容易,将会话范围代码更改为 POJO 和会话范围容器也不是那么容易。

Environment:

环境:

  • JDK 1.6
  • JBOSS 7.1.1
  • JDK 1.6
  • JBOSS 7.1.1

Solution:

解决方案:

As mentioned by Jan: Extend the StatelessBean as following:

正如 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();
    }

}

And the example is working! Now I just have to understand the details ;-)

这个例子是有效的!现在我只需要了解细节;-)

回答by jan groth

The problem is not to access to a session-scoped bean itself, the problem is that the session is not active, probably because it has never been started (e.g. EJB remoting).

问题不在于访问会话范围的 bean 本身,问题在于会话未处于活动状态,可能是因为它从未启动过(例如 EJB 远程处理)。

What you can do is starting a BoundSessionContextmanually, have a look here. I did that for conversations, and it worked fine.

你可以做的是BoundSessionContext手动启动,看看这里。我这样做是为了对话,而且效果很好。

回答by Ramanqul Buzaubak

you can't access session or store something in it with stateless beans, thats why they are called stateless! The only thing you can access is EjbContext, from it you can get caller principals and credencials, but don't forget to configure login module first.

您无法使用无状态 bean 访问会话或在其中存储某些内容,这就是它们被称为无状态的原因!您唯一可以访问的是 EjbContext,您可以从中获取调用者主体和凭据,但不要忘记先配置登录模块。