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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With