Here are the golden rules:
- You must have a
EntityManager
by interaction with the database1.
- You must have a
EntityManagerFactory
by database in the application (persistence Unit) and for ClassLoader
.
Most applications do not deal with ClassLoader
s directly and does not need to handle multiple versions of the same class in memory at the same time. Therefore in 99.9% of cases, rule number 2 can be simplified to:
- You must have a
EntityManagerFactory
by database in the application (persistence Unit).
Also, in about 98% of cases, the application only works with a single database. And therefore, rule number 2 can be simplified to:
- You must have a single
EntityManagerFactory
in the application.
And this suggests that you can use the design pattern Singleton:
public final class EntityManagerProvider {
private static final EntityManagerProvider INSTANCE = new EntityManagerProvider();
private final EntityManagerFactory factory;
private EntityManagerProvider() {
this.factory = Persistence.createEntityManagerFactory("SUA_BASE_DE_DADOS");
}
public static EntityManagerProvider getInstance() {
return INSTANCE;
}
public EntityManagerFactory getFactory() {
return factory;
}
public EntityManager createManager() {
return factory.createEntityManager();
}
}
This class above takes care of rule 2 perfectly. I suggest you implement rule number 1 in it as well, using a ThreadLocal
to maintain references to EntityManager
s and taking care not to reuse EntityManager
different requests, which can happen if your threads are in a pool and can be reused between different requests.
Also, the above code is easy to be modified to handle the case where there is more than one database. Just that each EntityManagerFactory
is in a class field EntityManagerProvider
and that each one is accessed by a different set of methods, or that you add a parameter to the relevant methods specifying which is the relevant database.
1 - In this context, a sequence of operations related to running consecutively in the database is defined by interaction with the database, possibly in a single transaction scope.
My suggestion for this case is to use the default Singleton. If the class
EntityManagerProvider
for its facade, it is easier to implement the Singleton in it. Otherwise you will have to create a class to implement this standard.– Wakim
@Wakim The Entitymanagerprovider class I created myself and am seeing about Singleton now. It really might be the solution. I will test.
– touchmx
For use, I would create a solution to Inject the Entitymanager where necessary. In simpler systems it is totally unnecessary, but for more complex applications it helps to decouple the system from a specific class, the code gets a little cleaner and the chances of errors occurring at runtime is less, since the objects or proxies are injected before the method begins to perform. Outside of an application server it is easy to achieve this using Spring, for example, but you can also use CDI using Weld.
– utluiz