【问题标题】:SessionContext getBusinessObject creates new beanSessionContext getBusinessObject 创建新 bean
【发布时间】:2013-01-11 05:47:50
【问题描述】:

我正在使用 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的错误?顺便说一句,有一个错误会影响通过 bean 的类获取业务对象的能力:https://issues.jboss.org/browse/EJBTHREE-2126。但是不确定它是否与我的问题有关。

【问题讨论】:

  • 这正是您使用 无状态 会话 bean 时它应该 的行为方式。您可能必须使用有状态会话 bean(或单例等)。
  • @home ,你确定吗?来自文档:docs.oracle.com/javaee/5/api/javax/ejb/…Obtain an object that can be used to invoke the current bean through the given business interface.
  • 嗯,你说得对,至少文档说明它应该在同一个 bean 上调用。但我猜这不一定是给定 bean 的同一个实例。返回另一个实例是有意义的,否则你会跨越事务边界......幸运的是我从未使用过该功能:-)

标签: java jakarta-ee jboss ejb-3.0 jboss5.x


【解决方案1】:

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

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;

如果这有帮助,请告诉我!

【讨论】:

    【解决方案2】:

    最好的解决办法是这样的:

    @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 注释,则调用自己不会造成任何死锁。

    【讨论】:

      猜你喜欢
      • 2011-11-29
      • 1970-01-01
      • 2016-04-13
      • 2015-01-14
      • 2015-03-15
      • 1970-01-01
      • 1970-01-01
      • 2021-11-09
      • 2016-11-07
      相关资源
      最近更新 更多