views:

41

answers:

2

Hey guys, my goal is create an EntityManager using properties dependent on which database is in use. I've seen something like this done in all my Google searches(I made the code more basic for the purpose of this question):

@PersistenceUnit
private EntityManagerFactory emf; 
private EntityManager em;
private Properties props;

@PostConstruct
public void createEntityManager(){

//if oracle set oracle properties else set postgres properties

emf = Persistence.createEntityManagerFactory("app-x");
em = emf.createEntityManager(props);
}

This works and I can load Oracle or Postgres properties successfully and I can Select from either database. HOWEVER, I am running into issues when doing INSERT statements. Whenever an INSERT is done I get a duplicate primary key exception.. every time! Can anyone shed some light on why this may be happening? Thanks -Brad

+1  A: 

Annotate your EntityManager with @PersistenceContext(unitName="app-x")

Thus you will not need to create new entity managers and factories - everything is automatically handled by your container.

Bozho
+1  A: 

In a container-managed environment, you can directly inject an EntityManager:

To obtain an EntityManager instance, inject the entity manager into the application component:

@PersistenceContext
EntityManager em;

If you need to deal with different persistence units (and thus several EntityManager instances), declare them in the persistence.xml and get the right EntityManager injected by its name:

@PersistenceContext(unitName = "MyFirstPU")
EntityManager em;

Update: According to Specifying the Database (and also mentioned this blog post), EclipseLink may be able to auto-detect the database platform and the eclipselink.target-database is optional:

If you are using the default persistence provider, the provider attempts to automatically detect the database type based on the connection metadata.

If this works with Oracle and PostgreSQL (and my understanding is that it should), the customer would only have to setup a datasource which is IMO the ideal scenario.

Pascal Thivent
My end goal is to have my app detect what type of database is being used(set in glassfish) and set up the EntityManager accordingly. My research points to using EntityManagerFactory as the best way to go. What do you think?
bradd
@bradd Why does your app need to detect the database? Can you elaborate a bit on this?
Pascal Thivent
Our goal is for our clients to be able to configure glassfish to use either postgres or oracle and not have to worry about modifying the persistence.xml file. We also want to stay away from creating different versions of the app for different databases.
bradd
I am now testing removing the database property from the persistence.xml. I guess we explicitly included the property because we were using a custom build of the postgres driver. However now it seems to be working without the explicit database property. Thanks for the tip.
bradd