Question

How is a Hibernate EntityManager to be used in a multi thread application (eg each client connection starts it's own thread on the server).

Should EntityManager only created once by EntityManagerFactory, like:

private static EntityManagerFactory emf = Persistence.createEntityManagerFactory("unit");
private static EntityManager em = emf.createEntityManager();
    public static EntityManager get() {
        return em;
    }

Or do I have to recreate the entitymanger for every thread, and for every transaction that closes the EM?

My CRUD methods will look like this:

public void save(T entity) {
    em.getTransaction().begin();
    em.persist(entity);
    em.getTransaction().commit();
    em.close();
}

public void delete(T entity) {
    em.getTransaction().begin();
    em.remove(entity);
    em.getTransaction().commit();
    em.close();
}

Would I havew to run emf.createEntityManager() before each .begin()? Or am I then getting into trouble because each is creating an own EntityManager instance with it's own cache?

Was it helpful?

Solution

5.1. Entity manager and transaction scopes:

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.

This answers perfectly your question. Don't share EMs over threads. Use one EM for several transactions as long as those transactions are part of a unit of work.

Furthermore you can't use an EntityManger after you've closed it:

After the close method has been invoked, all methods on the EntityManager instance and any Query, TypedQuery, and StoredProcedureQuery objects obtained from it will throw the IllegalStateException.

Consider something like this:

public class Controller {

    private EntityManagerFactory emf;

    public void doSomeUnitOfWork(int id) {
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();

        CrudDao dao = new CrudDao(em);

        Entity entity = dao.get(id);
        entity.setName("James");
        dao.save(entity);

        em.getTransaction.commit();
        em.close();
    }

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