Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate JTA : Read DB connection parameters per environment

I am writing a javaEE application, using hibernate. The application will be running on multiple environments (dev, qa, prod etc.) & will have separate dbs's associated with each of them. I would like to set the hibernate properties like jdbc-url, username , password etc. separately for each of these environments.

My current persistence.xml looks like :

    <persistence-unit name="PU" transaction-type="JTA">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <validation-mode>CALLBACK</validation-mode>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect" />
            <property name="hibernate.hbm2ddl.auto" value="validate" />

            <property name="hibernate.temp.use_jdbc_metadata_defaults" value="false"/>
            <property name="hibernate.event.merge.entity_copy_observer" value="allow"/>

            <property name="hibernate.connection.driver_class" value="oracle.jdbc.OracleDriver"/>
            <property name="hibernate.connection.url" value="jdbc:oracle:thin:@host/schema"/>

            <property name="hibernate.connection.username" value="abc"/>
            <property name="hibernate.connection.password" value="***"/>    

        </properties>
    </persistence-unit>

I am using the persistence unit as follows in my java code:

@PersistenceContext(unitName = "PU")
private EntityManager em; 

Is there a way that I can inject the hibernate properties, which are stored in separate properties files, into EntityManager for different environments ?

Please note that I am using JTA and hence cannot use EntityManagerFactory. Also I am not & do not want to use spring.

like image 410
Suraj Menon Avatar asked Oct 16 '15 08:10

Suraj Menon


3 Answers

It is really a BAAAAAAD idea to include environment-specific information in your application WAR/EAR bundle (either by including multiple configs, or by creating different bundles for different environment). Different database, for example, should be maintained in the container.

In your case, your persistence.xml should look like:

<persistence>
   <persistence-unit name="PU">
      <provider>org.hibernate.ejb.HibernatePersistence</provider>
      <jta-data-source>jdbc/fooAppDs</jta-data-source>
      <properties>
         ... ...
      </properties>
   </persistence-unit>
</persistence>

and of course you should have corresponding resource-ref for jdbc/fooAppDs.

By doing so, you can deploy your application in any environment. You just need to create correct datasource in your container and assign it to jdbc/fooAppDs.


Another approach I believe will work, though I will not recommend, is by creating hibernate.cfg.xml in classpath. You may want to have a local file system location and add that in classpath, instead of putting the file in your JAR/WAR/EAR.

like image 165
Adrian Shum Avatar answered Nov 30 '22 06:11

Adrian Shum


Since you do not want to use external library such as Spring to bootstrap your persistence units, why not use your build system to do this. If you are using maven, you can use mix of maven filtering and profiles to filter based on properties file or if you are using any other build tool, you can add a task (or equivalent) to copy file contents from different files to actual file depending upon some external system/environmental variable.

like image 25
Shailendra Avatar answered Nov 30 '22 08:11

Shailendra


We used maintain property files for each environment such as DEV,QA,PROD,UAT etc in different files and copy one of them during build.

Ant build

<property environment="env" /> 
                <!-- ***** COMMAND LINE ARGUMENTS DEMOED HERE -->
                <property name="build_type" value= "${env.build_type}"/>

<copy todir="deploy">
    <fileset dir="src_dir"/>
    <globmapper from=${env.build_type}".persistence.xml" to="persistence.xml"/>
 </copy>

Run build like this

ant -Denv.build_type=PROD

This will copy PROD.persistence.xml to persistence.xml

ant -Denv.build_type=DEV

This will copy DEV.persistence.xml to persistence.xml

like image 33
AGdev Avatar answered Nov 30 '22 08:11

AGdev