Java SessionContext getBusinessObject创建新bean

Java SessionContext getBusinessObject创建新bean,java,jakarta-ee,jboss,ejb-3.0,jboss5.x,Java,Jakarta Ee,Jboss,Ejb 3.0,Jboss5.x,我正在使用jboss5.1.0.GA(build:SVNTag=jboss_5_1_0_GA date=200905221634)。并且需要获得bean的业务接口。这是事务管理所必需的。 因此,我: @Local public interface MyBeanInterface { void transactionalMethod(); } @Stateless public class MyBean implements MyBeanInterface { @Resource

我正在使用jboss
5.1.0.GA(build:SVNTag=jboss_5_1_0_GA date=200905221634)
。并且需要获得bean的业务接口。这是事务管理所必需的。 因此,我:

@Local
public interface MyBeanInterface {
    void transactionalMethod();
}

@Stateless
public class MyBean implements MyBeanInterface {
    @Resource
    private SessionContext context;

    private int aState;

    public void someMethod() {
        aState = 42;
        context.getBusinessObject(MyBeanInterface.class).transactionalMethod();
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public void transactionalMethod() {
        System.out.println(aState); // 0!!!!!
    }
}
由于某些原因,我没有得到相同的bean,但是创建了新的bean。这是灾难性的,因为
transactionalMethod
需要状态变量值才能正确执行


我做错了什么,或者这是jboss的一个bug?顺便说一句,有一个bug会影响通过bean的类获取业务对象的能力:。但不确定是否与我的问题有关。

我没有时间查看语法是否完美,但您可以尝试:

InitialContext jndiContext = new InitialContext();
Object ref = jndiContext.lookup("projname/MyBeanInterface/local");
MyBeanInterfaceLocal m = (MyBeanInterfaceLocal) ref;
但是,我看到您有一个SessionContext字段,所以对于您来说,代码可能会有一点不同。也许是:

Object ref = SessionContext.lookup("projname/MyBeanInterface/local");
MyBeanInterfaceLocal m = (MyBeanInterfaceLocal) ref;

让我知道这是否有帮助

最好的解决方案是:

@Stateless
public class MyBean implements MyBeanInterface {

    @Resource private TransactionManager tm;

    private int aState;

    public void someMethod() {
        aState = 42;

        Transaction transaction = tm.suspend();

        transactionalMethod();

        tm.resume(transaction);
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public void transactionalMethod() {
        System.out.println(aState); // 0!!!!!
    }
}
当您通过ejb上下文从同一位置调用已发布的接口方法时,资源是:

  • 如果它是@Stateless,则会创建一个新实例
  • 如果是@Stateful,则为第一个调用创建一个新会话,然后其他调用与@Singleton相同
  • 如果它是@Singleton,调用方将等待释放资源,如果它自己调用,则会创建死锁。如果该方法用@Read注释,则调用自己不会创建任何死锁

当您使用无状态会话bean时,它的行为应该是这样的。您可能必须使用有状态会话bean(或单例,等等)。@home,您确定吗?从文档中:
获取一个对象,该对象可用于通过给定的业务接口调用当前bean。
Hm,您的正确答案是,至少文档中说明应该在同一个bean上调用它。但我猜这不一定是给定bean的同一个实例。返回另一个实例是有意义的,否则您将跨越事务边界。。。幸运的是,我从未使用过该功能:-)