Change JPA EntityManager connection properties at Runtime
There are many times you want to be able to use different connection options for a JPA EntityManager. The most obvious is different user-credentials (think of a user login-screen and re-using these credentials to connect to the DB), or to make the distinction between development/testing/production environment.
However, if you let Netbeans create the persistence configuration, it will hardcode all connection parameters into the persistence.xml file. When retrieving an EntityManager instance, it will use this information to connect.
If, instead you would like to do this at runtime, you can do the following:
- Remove the “properties” tag from the persistence.xml. This may not be necessary, but this will make it clear, that the properties are set inside the code.
- Create a “Map<String, String>” which will contain the properties. A list of standard properties can be found in the specs in section 8.2.1.9.
- Use this map to create an EntityManagerFactory and use this to create your EntityManager
An example persistence.xml without properties
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLo
<persistence-unit name="myTestPU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>my.package.Entity1</class>
<class>my.package.Entity2</class>
</persistence-unit>
</persistence>
In case Netbeans created a method “getEntityManager”, you can safely replace this. Here is an example I currently have in use. The “appConf” instance is a singleton I use to store configuration data in the user’s home folder, and yes, the password is stored in plain-text, but for this test-case I did not need to go any further:
Map<String, String> dbProps = new HashMap<String, String>();
dbProps.put("eclipselink.logging.level",
appConf.get("eclipselink.logging.level", "INFO").toString());
// On linux, the GSSAPI is not available. Use a default user/password
// pair to connect
if ("Linux".equals(System.getProperty("os.name"))) {
dbProps.put("javax.persistence.jdbc.url",
String.format("jdbc:jtds:sqlserver://%s/%s",
appConf.get("db.host", "my-default-host"),
appConf.get("db.database", "my-default-db")));
dbProps.put("javax.persistence.jdbc.driver",
"net.sourceforge.jtds.jdbc.Driver");
dbProps.put("javax.persistence.jdbc.password",
appConf.get("db.password").toString());
dbProps.put("javax.persistence.jdbc.user",
appConf.get("db.user", "my-default-username").toString());
} else {
dbProps.put("javax.persistence.jdbc.url",
String.format("jdbc:sqlserver://%s;databaseName=%s;integratedSecurity=true",
appConf.get("db.host", "my-default-host"),
appConf.get("db.database", "my-default-db")));
dbProps.put("javax.persistence.jdbc.driver",
"com.microsoft.sqlserver.jdbc.SQLServerDriver");
}
appConf.flush();
EntityManagerFactory fact = Persistence.createEntityManagerFactory("myTestPU", dbProps);
return fact.createEntityManager();
}
This example uses eclipselink. All available properties can be found it the EclipseLink Wiki
Posted in Coding Voodoo | 14 Comments »