Justas Justas - 1 year ago 216
Java Question

Guice and Hibernate - EntityManager thread safety

I have used this tutorial them same way in my application:

My app is JAX-RS web service which will receive many concurrent requests and make updates to database.

GenericDAOImpl.java implementation:

public class GenericDAOImpl<T> implements GenericDAO<T> {

protected EntityManager entityManager;

private Class<T> type;

public GenericDAOImpl(){}

public GenericDAOImpl(Class<T> type) {
this.type = type;

public void save(T entity) {


If 2 concurrent threads try to save entity, I get

java.lang.IllegalStateException: Transaction already active

Saving works well if I comment transaction.

I have tried to use

protected Provider<EntityManager> entityManagerProvider;


protected EntityManagerFactory entityManagerProvider;

and for each request:

EntityManager entityManager = entityManagerProvider.get()

But then I get:

org.hibernate.PersistentObjectException: detached entity passed to persist

What is correct way to implement Guice + Hibernate EntityManager injection / thread-safe generic DAO class?


Andrew Rayner comment from

"The logic isn’t really production ready – at least if used in a web app.

Hibernates connection pool is very basic and is not production ready – the recommendation is to use a datasource pool such as c3p0.

EntityManager shouldn’t be reused – it is intended to be created per transaction/request. There is a good chance of polluting subsequent requests.

There is also no transaction rollback if something goes wrong.

An interesting approach – but it would be much safer for webapps to use Guices own Persist extension module for managing the lifecycle of EntityMananger instances and transactions."

Answer Source

The problem was that my endpoint was annotated with @Singleton so it reused the same EntityManager during concurrent calls. After removing @Singleton, during concurrent calls, different EntityManager objects are used. If endpoint calls are subsequent, it may be that previous/old EntityManager will be used.

Highly simplified example:

public class ItemsService {

    private EntityManager entityManager;

    public void saveItem(){
         entityManager.persist(new Item());
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download