Change JPA EntityManager connection properties at Runtime

December 30th, 2010 by exhuma.twn

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:

  1. 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.
  2. 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.
  3. Use this map to create an EntityManagerFactory and use this to create your EntityManager

An example persistence.xml without properties

<?xml version="1.0" encoding="UTF-8"?>                                          
<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:

    private EntityManager getEntityManager() {                                  
                                                                               
        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 | 6 Comments »

  • khesraw

    This is exactly what i want but it is not so easy to understand please if you could give some explanation it will be my pleasure…

  • Pingback: how to give database user id and password at runtime not through persistence.xml file

  • http://foobar.lu exhuma.twn

    Thanks to Oracle, the link to the specs was broken. I fixed it now.

    @khesraw: What exactly is your problem? What parts do you not understand?

  • exhuma

    Thanks to Oracle, the link to the specs was broken. I fixed it now.

  • exhuma

    What exactly is your problem? What parts do you not understand?

  • Antonio D’Mora

     I have the same problem, I got lost in the part of the Entity Manager, where do I have to write that class??

Pages

Recent Posts

Categories

Links


Archives

Meta