13

EntityManager is not thread-safe by definition. Servlets specs says that in non-distributed environment and without implementing SingleThreadModel, there is only one servlet instance per definition.

Therefore, in Java EE when you inject an EntityManager through the @PersistenceContext into Servlet's field - it's not thread safe:

public class MyServlet extends HttpServlet {

    // Not thread-safe, should be using EMF instead.
    @PersistenceContext
    private EntityManager em;
}
  1. Is this correct to say that even though the default scope of Spring beans is singleton, the EntityManager is thread-safe as the Spring uses ThreadLocal to bind its transaction and EntityManager to it?

  2. Is the above Servlets example still valid in Spring? Is it still not thread-safe?

  3. Does the ThreadLocal approach works only for Spring managed beans and plain servlet is not one of those?

  4. As far as I remember, it's the container responsibility to inject the EntityManager. In Glassfish Java EE implementation, it was the application server who discovers the @PersistenceContext as injection point.
    How does it look like in Spring? Is the Spring Framework responsible for discovering those annotations or it's responsibility of the JPA implementor?

Piotr Nowicki
  • 17,914
  • 8
  • 63
  • 82

1 Answers1

7

Question 2, 3, and 4 -- Spring does not pay attention to any class that is not a Spring Bean. Therefor Spring does not pay attention to you MyServlet class. Therefore the answer for

  • 2) is no
  • 3) only Spring managed Beans
  • 4) it is Springs responsibility, because Spring is the Container

For Question 1). It works this way, so the usage of an Spring Injected Entity Manager is effective thread save.

Ralph
  • 118,862
  • 56
  • 287
  • 383
  • 1
    Thanks Ralph. So, by saying "2) is no" you mean that it's not thread-safe because this servlet is not a Spring bean, so in fact **no injection will occur at all**? Is it possible to mark such Servlet as a Spring bean? I somehow feel that's quite uncommon, not recommended and messy idea - it's just a theoretical question to understand Spring's mechanism. – Piotr Nowicki Apr 30 '12 at 08:40
  • 2
    I mean it is not a Spring bean at all (that is what is the the first paragraph about), so there is no injection and `em` will be null. -- Test it, if it is not null, then something really strange goes on. One way you can try to make it a spring bean is `@Configurable` but this requires real AspectJ and I have really no idea if this works for Servlets. – Ralph Apr 30 '12 at 08:53