• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

How to create EntityManagerFactory?

 
avihai marchiano
Ranch Hand
Posts: 342
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey,

I want to create EntityManagerFactory in runtime.

Means, that i dont want to use the persistence.xml file, because i will know the schema name only in runtime.

Any one has a knowledge or an example how to create EntityManagerFactory in my code ?


Thank you

ps - i am working with JBoss 4.2
 
Shailesh Kini
Ranch Hand
Posts: 153
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Avihai,

I wanted to create an EntityManagerFactory from the setUp method of my test framework. But after hours of banging my head on my desk I gave up. From what I have seen so far, unfortunately the answer is no. You have to provide an xml file with persistence unit name. However, you have an option to change the the connection info and other properties by providing then at runtime. You can call Persistence.createEntityManagerFactory(persistenceUnitName, properties) to override the default properties in the persistence.xml file.

But again I might be wrong. I am just a newbie with JPA so my knowledge is limited.
[ August 09, 2007: Message edited by: Shailesh Kini ]
 
Tony McClay
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You are correct. I have my refernces at home so I had to go to the orginal specification which yoy can download from java.sun.com site.

7.1.3.1 Persistence Unit Properties
Persistence unit properties may be passed to persistence providers in the Map parameter of the createEntityManagerFactory(String, Map) method. These properties correspond to the elements in the persistence.xml file. When any of these properties are specified in the Mapparameter, their values override the values of the corresponding elements in the persistence.xml file for the named persistence unit.

I have a code example at home. Let me know if you need me to post it. This should at least get you going in the right direction.

Tony
Sun Certified Web Business Component Developer
Sun Certified Web Components Developer
Sun Certified Programmer for the Java 2 Platform
 
avihai marchiano
Ranch Hand
Posts: 342
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Currently, I have a persistence.xml file and in run time i call to Persistence.createEntityManagerFactory and passed it the factory with overrides parameters.

one of the overrides parameters is the schema , becuse i know the schema only in run time.

I dont love it because in this way i create a dummy factory only in order to create a new factory based on it.

What is the meaning of the "dummy factory " ( it dosnt has a schema ).

Can you show your code.

Thank you.
 
Shailesh Kini
Ranch Hand
Posts: 153
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Avihai,

here's how I cache my emfFactory

private static Map<String, EntityManagerFactory> emfPUs = new HashMap<String, EntityManagerFactory>();

public static EntityManagerFactory getEMFactory(String pUName, Map properties){
EntityManagerFactory emfPU = emfPUs.get(pUName);
if (emfPU == null){
emfPU = Persistence.createEntityManagerFactory(pUName, properties);
emfPUs.put(pUName, emfPU);
}
return emfPU;
}

You could modify the above method to pass the schema name and store that as a key in the emfPUs.

your Map properties argument should have the schema name.

To get the EntityManager I use
public static EntityManager createEM(String pUName, Map properties) {
return getEMFactory(pUName, properties).createEntityManager(properties);
}

The magic is all done by the Map properties... which I set at runtime.
 
avihai marchiano
Ranch Hand
Posts: 342
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is exactly the way i do it.

The issue here that you have to have a factory in order to build new factories.

here is my perssistence.xml


My DS dosnt have a schema , so i dont ubderstand what is the meaning of the factory that build from this unit.
I mean to the first factory.

In run time i build my factories based on this factory with the schema as a param.
 
Sean Brown
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I override my properties too, but I have to override the entire data source at runtime. (The SQL database name is associated to the client's account)
I use Toplink Essentials and MySQL.

But.. Toplink caches the JDBC Connection, so if I create an entity manager a second time, while it says it's connected to the second database, it actually pulls entities from the conenction of the first entity manager created (per VM instance, of course).

If anyone knows how to stop this behavior or if another persistence provider (Hibernate, OpenJPA?) doesn't cache the connection, We would _love_ to hear about it.
 
Mike Keith
author
Ranch Hand
Posts: 304
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Sean Brown:
I override my properties too, but I have to override the entire data source at runtime. (The SQL database name is associated to the client's account)
I use Toplink Essentials and MySQL.

But.. Toplink caches the JDBC Connection, so if I create an entity manager a second time, while it says it's connected to the second database, it actually pulls entities from the conenction of the first entity manager created (per VM instance, of course).

If anyone knows how to stop this behavior or if another persistence provider (Hibernate, OpenJPA?) doesn't cache the connection, We would _love_ to hear about it.


Sean,

Connection information is coupled to the factory, not to the entity manager. This should be universally true (regardless of the provider). You might want to consider doing what the folks above are doing and have a different factory for each database configuration.
 
Sean Brown
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No, I've tried it. Toplink caches the JDBC Connection per Persistence Unit, so it is impossible to override the property and it have any effect. This may not be the case with another JPA Implementation, I don't know (I haven't been able to get most of them working).
I made a debug script which dumps the entire VM (especially toplink) and I can see the property being overridden, but I also see the Connection object has the same Identity as for the entity manager with the property set to a different connection url.
 
Mike Keith
author
Ranch Hand
Posts: 304
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Sean Brown:
No, I've tried it. Toplink caches the JDBC Connection per Persistence Unit, so it is impossible to override the property and it have any effect. This may not be the case with another JPA Implementation, I don't know (I haven't been able to get most of them working).
I made a debug script which dumps the entire VM (especially toplink) and I can see the property being overridden, but I also see the Connection object has the same Identity as for the entity manager with the property set to a different connection url.

A persistence unit is the same as a factory, so when you say that JDBC connections are cached in the persistence unit you are correct. Each persistence unit equates to a single EMF, which is bound to a specific data source configuration. It doesn't make sense to try to override the data source properties when you obtain a new EM from that same factory.

When you are creating the factory for the first time, however, I believe you can override the static data source config that is in persistence.xml with config in Java. Once your factory has been created it's data source config is fixed, although it may be possible to close the factory and then obtain a new one and be able to override the config again. Note once again that we are talking about factories, not EntityManagers. You can't obtain a new EM and change its data source config from previous EMs obtained from the same factory.
 
Sean Brown
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A: I was creating an entirely new factory for each EM I made, so I could indeed override the properties for each EM.

B: I fixed the problem by switching back to hibernate and fixing the other bug that was giving me beef (Hibernate out-of-the-box has problems with optional entity relationships which don't cascade deletes).
 
Mike Keith
author
Ranch Hand
Posts: 304
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Sean Brown:
A: I was creating an entirely new factory for each EM I made, so I could indeed override the properties for each EM.

B: I fixed the problem by switching back to hibernate and fixing the other bug that was giving me beef (Hibernate out-of-the-box has problems with optional entity relationships which don't cascade deletes).

Dude, don't do it. Factories are heavyweight and not meant to be created willy-nilly for every EM that you need. You are the second person in as many days that I have seen do this, and I'm getting scared
 
Sean Brown
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I *am* keeping the entity manager a long time. If it allows (ie. the connection doesn't time out?), for the life of the application; not for each transaction.
 
avihai marchiano
Ranch Hand
Posts: 342
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Since EM based on a connection it has time out (the default is 8 hours).

How you are going to handle transactions?

Can you post you code that handle the transaction?
there is a lot of issue in J2EE serevr
 
Mike Keith
author
Ranch Hand
Posts: 304
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Sean Brown:
I *am* keeping the entity manager a long time. If it allows (ie. the connection doesn't time out?), for the life of the application; not for each transaction.

Just a voice of warning that the reverse is also true. Just as factories are heavy, entity managers are meant to be lightweight, so keeping one open for an extended period of time is also not recommended. The resources are intended to be allocated for short time periods. For example, the persistence context will grow indiscriminately unless you manually clear it, and managing when to clear it, etc, is going to be more trouble than it's worth. Anyway, it's your app and your call (you've been warned, though :-)
 
ravinath fernando
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I spent 2 days with this problem. how ever i found a solution. is there another better way to done this,
need 2 step
{step1 : remove the properties want to load in run time in generated persistence.xml }
ex- i want to change user name and password

{step 2 : Create a Map in run time with property and desired value you can get values like an external XML configuration file}
thanks.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic