How to create a thread safe EntityManagerFactory?
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.
I am not seeing any issues with the static block approach. Or you can do the same in the below manner which is a Singleton pattern with double-lock check
public class JPAHelper {
private static JPAHelper myHelper = new JPAHelper();
private static EntityManagerFactory myFactory = null;
/**
* Private constructor. Implementing synchronization with double-lock check
*/
private JPAHelper() {
if(myFactory == null) {
synchronized (JPAHelper.class) {
// This second check will be true only for the first thread entering the block incase
// of thread race
if(myFactory == null) {
myFactory = Persistence.createEntityManagerFactory("MyUnit");
}
}
}
}
/**
* Static Accessor Method
* @return
*/
public static JPAHelper getInstance() {
if(myHelper == null) {
myHelper = new JPAHelper();
}
return myHelper;
}
public EntityManagerFactory getJPAFactory() {
return myFactory;
}
And you will call
EntityManager myManager = JPAhelper.getInstance().getJPAFactory().createEntityManager();