Reputation: 3175
I have many persistence units in my persistence.xml, one by postgreSQL schema.
I instantiate my EntityManager whenever I need by creating EntityManagerFactory dynamically :
EntityManagerFactory emf = Persistence.createEntityManagerFactory(schemaToChoose);
EntityManager em = emf.createEntityManager();
and it works fine. But thus, I don't use container injection.
Now, I wonder if it doesn't cost too much resources by this way ?
I don't probably understand well JPA cache but I believe that entities are stored inside em cache and inside emf cache, there are 2 levels. So when I instantiate em and emf each time I probably loose JPA cache and thus, I recreate it each time too.
I have 2 questions : could instantiate each time emf and em impact perfomances ? Should I inject as many em that I have schemas instead to keep cache ?
Thank you
Upvotes: 1
Views: 227
Reputation: 18389
You basically have a multi-tenant pattern. EJB injection doesn't handle this very well.
An EntityManagerFactory is not something you want to create more than once, and does contain the shared cache. (the share cache default is not specified by JPA, it is on by default in EclipseLink, but configurable through JPA cache-mode and @Cacheable and @Cache).
I would recommend some sort of registry for your factories. Perhaps this would even be an application object, such as your Universe.
public class Universe {
static Map<String, Universe> universes;
EntityManagerFactory emf;
public static Universe getUniverse(String schema) {
... hopefully you get the idea ...
}
public EntityManagerFactory getEntityManagerFactory() {
return emf;
}
}
Also, I would recommend you look into EclipseLink's multi-tenant support,
http://www.eclipse.org/eclipselink/documentation/2.4/jpa/extensions/a_multitenant.htm#BABEGBIJ
Upvotes: 0
Reputation: 692241
An EntityManagerFactory is a heavyweight, long-to-create object. It should be created only once, and then reused. Indeed, every time it's created, it parses the persistence.xml file, computes the mapping metadata of every entity, etc.
If you're running inside a Java EE container, then you should definitely let the container instantiate it for you, and inject the entity managers inside your EJBs.
I find it strange that a single application uses several database shemas. Why is it so?
Regarding the caches: there is a first-level cache associated with the entity manager (which is a short-lived cache, typically having the same life-time as a transaction. It's also possible to have a second-level cache, associated with the entity manager factory, but this is off by default, and, if enabled, must only be used for some entities and configured with care.
Upvotes: 2