How to create EntityManagerFactory secure thread?

I am working on an application that needs to perform some database operations.

I created a static variable for EntityManagerFactory and indexed it in the method that the application calls

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 an EntityManagerFactory in a synchronized block, the number of pending threads increases and crashes from the application.

I looked through the docs to make sure that Persistence.createEntityManagerFactory is thread safe without any success.

Please indicate me the necessary resources.

+7
java multithreading orm jpa
source share
5 answers

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

 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 has disappeared.

+11
source share

I see no problems with the static block approach. Or you can do the same in the following order, which is a Singleton pattern with double-lock validation.

 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(); 
+3
source share

You need to put locks on the object when creating emf. You can put locks on an emf object, but this is not the best practice. Create another object:

 private object factoryLockObject = new object(); 

and put your locks on it when creating a factory

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

What will help?

+1
source share

Regardless of whether createEntityManagerFactory() thread safe or not, you need some strategy so that it is called only once. In other words, this question does not matter, because you have to make sure that only one thread causes it.

If you just expect another thread to create a factory to crash your application, what happens when each thread creates its own, knocking down other threads in the process?

The code you show must be inside a synchronized block or not thread safe.

+1
source share

Answer to the question: YES, createEntityManagerFactory () is thread safe based on documentation on classes, source and real applications.

The answer to the Singleton pattern is most correct in order to avoid an additional call to efficiently get the factory descriptor, but note that there is no need to block double checking, as was previously commented.

0
source share

All Articles