1
votes

I have a @Singleton EJB, in which I inject another EJB which is not Singleton (it is either @Stateless or @Statefull). E.g.

@Singleton
public class MySingleton {
    @EJB
    MyStatefulBean statefulBean;//this is stateful!

    public void doSomething() {
        statefulBean.something();
    }
}

My question is: will statefulBean always have the same reference or will it somehow differ at each call of doSomething()? Since we have a singleton, it would make sense that statefulBean always has the same reference. Still, I'm asking since I'm new to EJBs and want to be sure. Thanks!

2

2 Answers

1
votes

Every time doSomething is called - you get statefulBean that connected with current session, which is responsible for this singleton call. During the method execution you Singleton ejb is locked and no other method of this Singleton ejb can be called beside the objects that have direct reference to this ejb normally ejb object self, because other objects get proxy object reference. Furthermore, during method execution no other objects can be injected into this ejb. This is possible because singleton was designed for concurrent access, and default concurrency settings for Singleton ejb's are ConcurrencyManagementType.CONTAINER and LockType.WRITE. You can change this behavior but keep in mind that then you Singleton ejb can be called from multiple threads at the same time and you can get unexpected results a special if you Inject statefull object. More about concurrency control of singleton ejb's you can read there.

0
votes

My question is: will statefulBean always have the same reference or will it somehow differ at each call of doSomething()?

Here is what the EJB specification states about it:

3.4.7.1Stateful Session Beans

A stateful session object has a unique identity that is assigned by the container at the time the object is created. A client of the stateful session bean business interface can determine if two business interface or no-interface view references refer to the same session object by use of the equals method.

For example,

@EJB Cart cart1;

@EJB Cart cart2;

...

if (cart1.equals(cart1)) { // this test must return true
    ...  
}
...

if (cart1.equals(cart2)) { // this test must return false
    ...
}

All stateful session bean references to the same business interface for the same stateful session bean instance will be equal. All references to the no-interface view of the same stateful session bean instance will be equal. Stateful session bean references to different interface types or between an interface type and a no-interface view or to different session bean instances will not have the same identity.

This means that once the client has acquired a reference to a stateful session bean that bean is bound to the client. The client can set and read the states of the bean. When the client is finished it must inform the server that the bean should be destroyed by invoking a method annotated by a @Remove annotation.