5

We are designing an application using Spring-Hibernate where 6 threads run simultaneously. Each thread performs a different operation and inserts/updates a few records in common table(all threads work on common tables).

While we know that we can have just one single instance of EntityManagerFactory, we are not sure how many instances of EntityManager should we have? Should we create six entity managers(one for each thread)? How should we create the DAO? Should we just create one EntityManager like following and use the same dao class for all the threads? I know EM specification says that it's not thread safe, but I read somewhere that injected EM in the case of spring are threadsafe(I wasn't convinced with the explanation, though).

@Trasactional
public class myAppDao { 
@PersistenceContext
private EntityManager entityManager;
..
}

or should we do something different ?

bluelurker
  • 887
  • 3
  • 15
  • 24
  • See this http://stackoverflow.com/questions/14888040/java-an-entitymanager-object-in-a-multithread-environment – Subin Sebastian Feb 06 '17 at 18:03
  • 1
    `Entity managers are not thread-safe But, if the injector is injecting each thread with its own entity manager then things should be OK.Spring and possibly other DI frameworks will inject a ThreadLocal-based proxy for a real entity manager into your beans. Calls that each thread makes will proxy to the real thread-local instance of an entity manager - this is how things can work even though it might appear an entity manager is shared among multiple threads.` – Subin Sebastian Feb 06 '17 at 18:05

1 Answers1

8

Yes, usually the EntityManager or Session are bound to the thread (implemented as a ThreadLocal variable). @PersistenceContext annotation is recognized by Spring IoC/CDI and is treated in a special way to enable this.

There is some layer in your app (usually marked as @Transactional) that creates EntityManager and binds it to the ThreadLocal variable. This happens every time the 1st @Transactional is invoked. And same - EntityManager is closed every time the method exits.

Alternatively this can be implemented using OpenSessionInViewInterceptor or OpenSessionInViewFilter.

Stanislav Bashkyrtsev
  • 11,403
  • 7
  • 33
  • 38