Difference between @Stateless and @Singleton
Asked Answered
I

2

43

I'm following this tutorial which also uses an EJB:

package exercise1;

import java.util.Random;
import javax.ejb.Stateless;
import javax.inject.Named;

@Stateless
public class MessageServerBean {
    private int counter = 0;

    public String getMessage(){
        Random random = new Random();
        random.nextInt(9999999);
        int myRandomNumber = random.nextInt();
        return "" + myRandomNumber;
    }

    public int getCounter(){
        return counter++;
    }    
}

Here is an output example:


Hello from Facelets
Message is: 84804258
Counter is: 26
Message Server Bean is: exercise1.MessageServerBean@757b6193


Here's my observation:

  • When I set the bean as @Stateless I always get the same object ID and counter always increments.
  • When I set the bean as @Stateful I get a new instance every time I refresh the page.
  • When I set it to @Singleton I get the same results as when I set it to @Stateless: same object ID, counter incrementing.

So, what I actually would like to understand is: what's the difference between @Stateless and @Singleton EJBs in this very case?

Intracranial answered 22/1, 2013 at 17:45 Comment(0)
H
48

You're seeing the same output because there is only one client accessing the EJB at a time. The application server is able to recycle the same stateless EJB object for each call. If you try a concurrent access – multiple clients at the same time - you'll see new stateless instances appearing.

Note that, depending on the server load, even two consecutive method invocations made by the same client may end up in different stateless EJB objects!

For a singleton EJB, there will no difference – there is always only one instance per application, no matter how many clients try to access it.

Handedness answered 22/1, 2013 at 19:12 Comment(1)
An easy way to see multiple instances (rather than setting up concurrent calls) is to call a stateless bean from within the same stateless bean. That is: @Stateless public class MyBean { @EJB MyBean bean; public void test() { System.out.println(this + ".test"); bean.test2(); } public void test2() { System.out.println(this + ".test2"); } }Lupine
K
40

According to the Oracle Documentation:

Singleton session beans offer similar functionality to stateless session beans but differ from them in that there is only one singleton session bean per application, as opposed to a pool of stateless session beans, any of which may respond to a client request. Like stateless session beans, singleton session beans can implement web service endpoints.

Singletons can't be passivated:

Like a stateless session bean, a singleton session bean is never passivated and has only two stages, nonexistent and ready for the invocation of business methods(...)

The documentation explains when to use each kind of bean, and Singleton beans has the following:

A single enterprise bean needs to be accessed by multiple threads concurrently.

The application needs an enterprise bean to perform tasks upon application startup and shutdown.

So, for your example there's no difference between the two annotations.

Kob answered 22/1, 2013 at 18:8 Comment(2)
thank you so much kauedg! (sorry for replying so late, I didn't see the notification...)Intracranial
Great find. Thanks.Pino

© 2022 - 2024 — McMap. All rights reserved.