Spring : @PersistenceContext and @Autowired thread safety

jpajpa-2.0spring

based on this example :

@Service
public class Purchase {
  @PersistenceContext
  private EntityManager em;

  @Autowired
  private PurchaseDAO dao;

  private String normalField;

  .... // methods, operations, etc
}

Please help correct me if im mistaken :

  1. The service class Purchase and the PurchaseDAO are singletons that are managed by spring
  2. The service class's field normalField is not threadsafe, because singleton is a single object shared by many
  3. Let's assume the @Repository-annotated-PurchaseDAO doesnt have any field, which means it's threadsafe, will be injected automatically by spring
  4. The EntityManager instance is also a threadsafe property because @PersistenceContext will make sure that the entityManager of the current transaction will be used.

Thank you !

Best Solution

  1. They are singletons by default (when they are Spring managed), unless you have configured them otherwise (from either the xml-configuration or with annotations you can set it with @Scope).
  2. Yes and no. Yes, it's not safe in the sense that multiple threads can access and modify it simultaneously, and no because it depends on the data type and String is immutable (and at least said to be thread safe). It could possibly blow up if two different threads tried to store a new string in the member variable at the exact same moment.
  3. Yes and no again. If the DAO has no internal state, yes, I'd say it's thread safe, but the objects it is handling might not be (although if you're using JPA-entities, they should be).
  4. At least Hibernate's documentation says that EntityManagers are not threadsafe, but when using an EntityManager injected by Spring, it shouldn't be an issue.

SpringSource forums: I have been looking for answers to the same question on the forum... The general concensus seems to be that while EntityManager is not thread safe per JPA specs, the EntityManager injected by Spring through its EntityManager proxy may be.

Hibernate: An EntityManager is an inexpensive, non-threadsafe object that should be used once, for a single business process, a single unit of work, and then discarded. An EntityManager will not obtain a JDBC Connection (or a Datasource) unless it is needed, so you may safely open and close an EntityManager even if you are not sure that data access will be needed to serve a particular request.