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.
EntityManagerFactory instances are thread-safe. Applications create EntityManager instances in this case by using the createEntityManager method of javax. persistence. EntityManagerFactory .
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.
No, an EntityManager is NOT thread safe.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With