Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a thread safe EntityManagerFactory?

I'm working on an application that needs to do some database operations.

I created a static variable for EntityManagerFactory and initializeded it in the method that gets called by the application

 if (emf == null) {
      emf = Persistence.createEntityManagerFactory("example");
 }

 try {
      em = emf.createEntityManager();
 } catch (Exception ex) {
      logger.error(ex.getMessage());
 }

Is this thread-safe? If I create the EntityManagerFactory in a synchronized block, the number of the waiting threads increases and crashes the application.

I looked at the docs to see whether the Persistence.createEntityManagerFactory is thread-safe without any success.

Please direct me to the right resources.

like image 494
Vanchinathan Chandrasekaran Avatar asked Sep 14 '10 17:09

Vanchinathan Chandrasekaran


People also ask

Is EntityManagerFactory thread safe?

EntityManagerFactory instances are thread-safe. Applications create EntityManager instances in this case by using the createEntityManager method of javax. persistence. EntityManagerFactory .

Is Persistencecontext thread safe?

To my great surprise (after years of using jpa in spring) EntityManager is not thread safe. This is actually understandable if you think about it deeper: EntityManager is just a wrapper around native JPA implementation, e.g. session in Hibernate, which in turns is a wrapper around jdbc connection.

Is the JPA EntityManager object thread safe?

No, an EntityManager is NOT thread safe.

What is EntityManager Factory?

An EntityManagerFactory is constructed for a specific database, and by managing resources efficiently (e.g. a pool of sockets), it provides an efficient way to construct multiple EntityManager instances for that database.


1 Answers

An easy way to "solve" this would be to use a helper class (a la HibernateUtil) and to initialize the EntityManagerFactory in a static initialization block. Something like this:

public class JpaUtil { 
    private static final EntityManagerFactory emf;

    static {
        try {
            factory = Persistence.createEntityManagerFactory("MyPu");
        } catch (Throwable ex) {
            logger.error("Initial SessionFactory creation failed", ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

   ...

}

And the "problem" is gone.

like image 132
Pascal Thivent Avatar answered Sep 30 '22 08:09

Pascal Thivent