JavaEE & JAX-RS: Should resource class be declared as Singleton or stateless?

Looking at listing # 1 in after the tutorial ,

JAX-RS resource classes can be defined as @Stateless or @Singleton.

I have the following code in my application:

@Stateless
public class VisitDaoImpl implements VisitDao {

    @PersistenceContext(name = "MysqlPU")
    private EntityManager em;

    @Override
    public void persist(Visit vist) {
        em.persist(vist);
    }
}

@ApplicationPath("rest")
public class ApplicationConfig extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> resources = new java.util.HashSet<>();
        resources.add(WelcomeResource.class);
        return resources;
    }
}

//@Singleton
@Stateless
@Path("/Welcome")
public class WelcomeResource {

    @EJB
    private VisitDao visitDao;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String wellcomeMessage() {
        visitDao.persist(new Visit())
        return "Welcome";
    }
}

      

As you can see, I have no state in my resource class other than Dao bean.

My questions:

  • Should I be using @Stateless or @Singleton bean here?
  • When would you use one of these in another JAX-RS resource class?

Thank.

+3


source to share


3 answers


I think @Stateless if you want to do database write operations or other methods that affect state.

Multiple threads (clients) will have to wait for the singleton to become available by default. The lock is written to singleton-ejbs.

from the java-ee-6 tutorial:

Annotating a singleton class with @Lock specifies that all business methods and any singleton timeout methods will use the specified lock type unless they explicitly set the lock type using the method-level @ method annotation. If the @Lock annotation is missing from the singleton class, the default lock type, @Lock (WRITE), applies to all business and timeouts.



In this example, there is an ejb-dao between your @ Path-ejb and the database. Which hints you can change to @Singleton and use @Lock (READ) for your business method (not sure why anyone would want to try).

But I don't think it is safe as the same ejb-dao instance will be used for all concurrent calls made by clients and the EntityManager that holds the DAO is not thread safe:

from the java-ee-6 tutorial:

Application managed entity administrators are used when applications need to access a persistence context that is not propagated by JTA transaction across EntityManager instances to a certain extent Block. In this case, each EntityManager creates a new isolated persistence context. The EntityManager and its associated persistence context are explicitly created and destroyed by the application. They are also used when direct nesting of EntityManager instances cannot be done because EntityManager instances are not thread safe . EntityManagerFactory instances are thread safe.

+3


source


For the recommended approach for stateless objects for Singleton in Spring, see this question and Spring current guide . Thus, according to Spring, you should use Singleton since your Restore service is statusless.

5.5.2 Prototype area

The non-elementary, prototypal bean deployment scope results in a new bean instance being created every time a request is made for that particular bean. That is, a bean is injected into another bean, or you request it through a call to the getBean () method in the container. Typically use a prototype scope for all beans states and singleton for apathy beans.



But according to the Enterprise beans Java Tutorial , you can use either a stateless bean or a singleton as they explicitly state that "the bean implements a web service ." for both stateless and singles. But a stateless bean might be the best choice due to the single hooks . Finally, use a singleton in Spring, a stateless bean in JavaEE.

+1


source


First : in your case, I think the answer should be "no". There is no reason for your JAX-RS class to be an EJB as well. You can add an EJB to it (JAX-RS supports this) so that all your EJB-ey stuff (like database transactions) in EJB applications (like yours VisitDao

) and keep the REST classes small and simple - remember: principle single responsibility .

@Stateless

or @Singleton

I see that people tend to use @Stateless

. As explained in other answers, this results in an EJB pool, as EJB assumes by default that your classes are not thread safe, so it will never resolve multiple threads at once into one instance. The pool size is controlled by the application server configuration. If more threads want to access the session bean than there are instances available in the pool (and the maximum pool size does not allow for more), the thread must wait.

Because of this risk of thread conflicts when working in high traffic situations, plus the fact that if you program your session beans correctly, they will actually be thread safe, I started moving into a template where I comment out my EJBs as @Startup @Singleton ConcurrencyManagement(ConcurrencyManagementType.BEAN)

. It means:

  • only one bean instance will be created (so you don't waste memory on multiple instances)
  • it will be created as soon as your application starts (so there will be no more expensive and time consuming resource allocation after starting your application and requests will start coming in)
  • your bean is responsible for managing concurrency, that is, being thread safe (just make sure that after creation and initialization, you don't change any of the bean fields and you should be fine - this is good practice anyway)

By the way, this is the default in Spring for beans, and I think it is good (I have a Spring background so I cannot be completely unbiased).

0


source







All Articles