Question

I am using a Service Locator implementation which caches the result of javax.naming.Context#lookup call, and maps it to the requested EJB interface, so all subsequent requests (for the same EJB) after the first one, return the cached instance.

My concerns are:

  1. Since the same instance is used, there is no utilization of the server EJB pool which would serve multiple simultaneous requests with multiple EJBs (unless the underlying server logic somehow makes use of the EJB pooling)
  2. Stateless and stateful EJBs are thread safe, but since, again, only one instance per EJB class is used, and EJB has EntityManager injected via @PersistenceContext, I assume that means that multiple threads could be using the same EntityManager instance (not just the persistence context), which definitely is not thread-safe

Do you think that it's best not to use caching in the Service Locator, or that my concerns are unjustified regarding EJB behavior?

Was it helpful?

Solution

What you get from the lookup operation (through the JNDI service) is an object called Stub and him is not fixed with any special EJB instance.

Once cached, every time you invoke an EJB service the stub is able to select a different EJB instance from the pool (this apply to stateless); even in a cluster environment, the stub object is able to select an EJB instance from different servers.

Therefore, caching the stub object should not be a problem.

Notice that I'm talking about stateless, I think that caching doesn't make sense to statefull session bean.

The EJB lookup is a time-consuming operation, so caching improves the client performance.


About your comment:

If you were using EntityManager inside a component that is used by multiple concurrent threads like a Servlet, yes, you will have to care about concurrency, but the EJB's Tread Model imply that will not be several thread using the same EntityManager instance at the same time, so the fact that EM is not thread safe doesn't matter.

What concerns me still is the fact that different EJBs are using the same injected (via @PersistenceContext) EntityManager instance

I think that for simple sceneries the best way to think about it, if as describe here:

The most common pattern in a multi-user client/server application is entitymanager-per-request. In this model, a request from the client is send to the server (where the JPA persistence layer runs), a new EntityManager is opened, and all database operations are executed in this unit of work. Once the work has been completed (and the response for the client has been prepared), the persistence context is flushed and closed, as well as the entity manager object.

This will be more difficult to check ;)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top