aspose file tools*
The moose likes Object Relational Mapping and the fly likes How to create EntityManagerFactory? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of JavaScript Promises Essentials this week in the JavaScript forum!
JavaRanch » Java Forums » Databases » Object Relational Mapping
Bookmark "How to create EntityManagerFactory?" Watch "How to create EntityManagerFactory?" New topic
Author

How to create EntityManagerFactory?

avihai marchiano
Ranch Hand

Joined: Jan 10, 2007
Posts: 342
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

Joined: Oct 17, 2001
Posts: 153
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 ]

Shailesh Kini.
Tony McClay
Ranch Hand

Joined: May 22, 2003
Posts: 33
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


Tony McClay<br />Architect / Developer, SOA and Jave Enterprise Edition 1-5<br />---------------------------------------------------------------------- <br />Sun Certified Enterprise Architect, Enterprise Edition 5 (Step 1 of 3)<br />Sun Certified Web Component Developer, Enterprise Edition 4<br />Sun Certified Business Component Developer Enterprise Edition 5<br />Sun Certified Programmer , Standard Edition 5.0
avihai marchiano
Ranch Hand

Joined: Jan 10, 2007
Posts: 342
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

Joined: Oct 17, 2001
Posts: 153
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

Joined: Jan 10, 2007
Posts: 342
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

Joined: Jun 11, 2007
Posts: 11
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

Joined: Jul 14, 2005
Posts: 304
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.


-Mike
Pro JPA 2: Mastering the Java Persistence API
Sean Brown
Greenhorn

Joined: Jun 11, 2007
Posts: 11
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

Joined: Jul 14, 2005
Posts: 304
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

Joined: Jun 11, 2007
Posts: 11
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

Joined: Jul 14, 2005
Posts: 304
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

Joined: Jun 11, 2007
Posts: 11
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

Joined: Jan 10, 2007
Posts: 342
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

Joined: Jul 14, 2005
Posts: 304
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

Joined: Jan 22, 2013
Posts: 1
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.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: How to create EntityManagerFactory?