This week's giveaway is in the Android forum.
We're giving away four copies of Android Security Essentials Live Lessons and have Godfrey Nolan on-line!
See this thread for details.
The moose likes EJB Certification (SCBCD/OCPJBCD) and the fly likes Mess with EntityManagers and EntityManagerFactory Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Certification » EJB Certification (SCBCD/OCPJBCD)
Bookmark "Mess with EntityManagers and EntityManagerFactory" Watch "Mess with EntityManagers and EntityManagerFactory" New topic
Author

Mess with EntityManagers and EntityManagerFactory

Ana Va
Greenhorn

Joined: Nov 24, 2008
Posts: 8
Hi!! I have a mess with this classes and I would thank some help with them!!

This is my problem: I have an application with 2 Persistence Units ("UP_Produccion" and "UP_Practicas"), and I need to be connected to both all the time (because clients will need to execute querys on both).
I had it like this: (this is an example of class "UsuarioFacade"):
@PersistenceContext(unitName="UP_Produccion")
private EntityManager em_produccion;
@PersistenceContext(unitName="UP_Practicas")
private static EntityManager em_practicas;

public List validar(int entorno, String consulta) {
if (entorno == 1){
return em_practicas.createQuery(consulta).getResultList();
}else{
return em_produccion.createQuery(consulta).getResultList();
}
}

It worked ok, but now, I�m trying to obtain EntityManager objetcs from another class (in order to avoid repeating this code in every Facade).
I would like to have something like this in UsuariosFacade:

public List validar(int entorno, String consulta) {
Controler.createQuery(entorno, consulta);
}

And Controler should choose the EntityManager to work with:
@PersistenceContext(unitName="UP_Produccion")
private static EntityManager em_produccion;
@PersistenceContext(unitName="UP_Practicas")
private static EntityManager em_practicas;

public List createQuery (int entorno, String consulta){
if (entorno == 1){
return em_practicas.createQuery(consulta).getResultList();
}else{
return em_produccion.createQuery(consulta).getResultList();
}
}

It didn�t work, so I tried to have EntityManagerFactory objects instead of EntityManager:
EntityManagerFactory emf_prod;
EntityManagerFactory emf_pract;

private ControlConexion() {
emf_prod = Persistence.createEntityManagerFactory("UP_Produccion");
emf_pract = Persistence.createEntityManagerFactory("UP_Practicas");
}

public List createQuery (int entorno, String consulta){
if (entorno == 1){
return emf_pract.createEntityManager().createQuery(consulta).getResultList();
}else{
return emf_prod.createEntityManager().createQuery(consulta).getResultList();
}
}

And it didn�t work either!!

I�m not sure if I�m using these objects propertly. Could anyone help me???

(I'm sorry if my English is not good. Please, ask me if I didn�t explain anything clearly...)
Thanks a lot for your help!!
Ana Va
Greenhorn

Joined: Nov 24, 2008
Posts: 8
I just need to know how can I get the EntityManager objects (for 2 different Persistence Units) in a class which is not a Bean.
Do I need to use EntityMangerFactory?

Please.... any help???
Ralph Jaus
Ranch Hand

Joined: Apr 27, 2008
Posts: 342
Hi Ana,
I just need to know how can I get the EntityManager objects in a class which is not a Bean.
Are you working with ejb's or with a standalone java application ? In an ejb environment it is no problem to inject two entity managers that use different persistence units.


SCJP 5 (98%) - SCBCD 5 (98%)
Ana Va
Greenhorn

Joined: Nov 24, 2008
Posts: 8
I�m working with ejbs.
But my problem is that when I manage EntityManager objects in a class that is not an ejb, it doesn�t work...

Class UsuariosFacade (it is an ejb)
@PersistenceContext(unitName="UP_Produccion")
private EntityManager em_produccion;
@PersistenceContext(unitName="UP_Practicas")
private static EntityManager em_practicas;

public List validar(int entorno, String consulta) {
if (entorno == 1){
return em_practicas.createQuery(consulta).getResultList();
}else{
return em_produccion.createQuery(consulta).getResultList();
}
}

This works ok. But is I create another class "ControlConexion" which is not an ejb it doesn�t work:

@PersistenceContext(unitName="UP_Produccion")
private EntityManager em_produccion;
@PersistenceContext(unitName="UP_Practicas")
private static EntityManager em_practicas;

public List createQuery (int entorno, String consulta){
if (entorno == 1){
return emf_pract.createEntityManager().createQuery(consulta).getResultList();
}else{
return emf_prod.createEntityManager().createQuery(consulta).getResultList();
}
}

In UsuariosFacade, I call ControlConexion�s method:

public List validar(int entorno, String consulta) {
ControlConexion.createQuery(entorno, consulta);
}


Do you know why??
Ana Va
Greenhorn

Joined: Nov 24, 2008
Posts: 8
I mean, that I want to move the code related to EntityManager objects to another class that will be call in all the beans (to make future changes easily). And this other class is not a bean.
Ralph Jaus
Ranch Hand

Joined: Apr 27, 2008
Posts: 342
Dependency injection only works with bean classes or superclasses thereof. I see the following solutions:

1. Use a constructor for ControlConexion the gets the entity managers as input.

2. Use a jndi lookup for the entity managers within ControlConexion.

By the way, the ejb 3 specification says that static variables should only be used for constants. So your definition of em_practicas contradicts the specification and isn't portable.
Ana Va
Greenhorn

Joined: Nov 24, 2008
Posts: 8
I�m not quite sure if I understood:

1. I should get the EntityManager object in a bean, and pass it to the ControlConexion?? But I want to do the opposite, I want to avoid having both EntityManager in all the beans, and checking "if (entorno == ..." in all the beans. Then, if I have another Persistence unit some day, I will make changes only in ControlConexion.

2. How can I do this?? I don�t understand this option...

You�re right, the variables should not be static, is a mistake (I forgot to change it after a test).

And what about EntityManagerFactory? I read something that made me think that it�s used when you are not in a bean, to get the right context, isn�t it? Maybe I�m wrong, but I was trying to use it in my "ControlConexion" to get the injection to the EntityManager objects (is this said this way??)

Please, be patient with me... sometimes it�s dificult to express and understand this problems in English...
Anyway, thank you for you time and your ideas!!
[ November 24, 2008: Message edited by: Ana Va ]
Ana Va
Greenhorn

Joined: Nov 24, 2008
Posts: 8
I tried to pass the EntityManager to the constructor of ControlConexion, and It worked!!!

ControlConexion:


UsuariosFacade:


The "validar" method is the first one called in the login. In this method, I call the getInstance(em1, em2) to get and store the EntityManager objects. Then, I need to have another "getInstance()" (and another constructor ControlConexiones()), to call it in the following querys, so it will use the EntityManagers stored. I�m going to try these other methods now, but I hope they will work!!
Maybe it�s a bit strange, but it�s the only way I cant imagine...

I�m going to try and I will tell you now...
Ana Va
Greenhorn

Joined: Nov 24, 2008
Posts: 8
It seems to work perfectly!!

This should be the code for any UsuariosFacade (the first one called for the client, that has the EntityManager objects):



The other "Facades":
They wont have any variables, and all the calls will be "ControlConecion.getInstance().whatever..."

The code of ControlConexiones should be:




I will tell you if I get any problem, just in case someone reads this having the same problem, although it seems unprobable!! ;-)

Thank you Ralph for you help!!!
Ralph Jaus
Ranch Hand

Joined: Apr 27, 2008
Posts: 342
If it's possible to inherrit your bean classes from the same base class, say "Base", you can also use a construction like No persistence contexts are needed in the bean classes. If you need to integrate a new persistence unit you have to add a corresponding @PersistenceContext in Base and adjust the constructor of ControlConexion. The problem is that you may have to redeploy older beans even if they don't use the new persistence unit.

Alternatively you can try the way used in standalone java applications via the Persistence class. It looks like

EntityManagerFactory emf = Persistence.createEntityManagerFactory("persistenceUnitName");
EntityManager em = emf.createEntityManager();

This code would be used in ControlConexion. Dependency injection isn't needed. I don't know the necessary configuration of the persistence.xml file in this case, but surely you can find them out by googling.
[ November 24, 2008: Message edited by: Ralph Jaus ]
Ana Va
Greenhorn

Joined: Nov 24, 2008
Posts: 8
I tried your last idea, but without the Base class (because I have 80 Facades that I should change to try it!). I supose it�s the main part, because it didn�t work without it!
I got this exception: javax.naming.NameNotFoundException: env not bound.

At least, the solution posted yesterday works, although it�s not the best one!
[ November 25, 2008: Message edited by: Ana Va ]
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Mess with EntityManagers and EntityManagerFactory
 
Similar Threads
Persistence IllegalArgumentException in EntityManager
Exception in deployment of ejb ear
spring wont inject the entitymanager
Override AbstractFacade ?!
update using JPA