5

I need to be able to store database config properties in src|main|java|dbConnection.properties and include it to hibernate.cfg.xml in form of jstl expressions. (like : ${password} etc.). How to do it?

Current hibernate.cfg.xml:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
<property name="connection.driver_class">org.postgresql.Driver</property>
        <property name="connection.username">postgres</property>
        <property name="connection.password">postgres</property>
        <property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
    </session-factory>
</hibernate-configuration>

I need something like this:

<?xml version='1.0' encoding='utf-8'?>
    <!DOCTYPE hibernate-configuration PUBLIC
            "-//Hibernate/Hibernate Configuration DTD//EN"
            "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
        <session-factory>
    <property name="connection.driver_class">${DRIVER}</property>
            <property name="connection.username">${USERNAME}</property>
            <property name="connection.password">${PASSWORD}</property>
            <property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
        </session-factory>
    </hibernate-configuration>
J.Olufsen
  • 13,415
  • 44
  • 120
  • 185
  • 1
    If you are using Spring why even bother with a hibernate.cfg.xml. Configure the `SessionFactory` in spring and let spring handle the placeholder replacement for you. – M. Deinum Jun 12 '14 at 05:31

3 Answers3

8

You state that you use Spring then why not let Spring do all the hard work. Let a property placeholder replace the placeholders you want.

<context:property-placeholder location="classpath:dbConnection.properties" />

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="hibernateProperties">
       <map>
            <entry key="connection.driver_class" value="${DRIVER}" />
            <entry key="connection.username" value="${USERNAME}" />
            <entry key="connection.password" value="${PASSWORD}" />
            <entry key="transaction.factory_class" value="org.hibernate.transaction.JDBCTransactionFactory" />
        </map>
    <property>
 </bean>

Free advice instead of using the internal hibernate connection stuff (which isn't adviced to be used in production) configure a datasource in spring and wire that to your LocalSessionFactoryBean

J.Olufsen
  • 13,415
  • 44
  • 120
  • 185
M. Deinum
  • 115,695
  • 22
  • 220
  • 224
6

You can do it programmatically.

hibernate.cfg.xml should be as following.

<?xml version='1.0' encoding='utf-8'?>
    <!DOCTYPE hibernate-configuration PUBLIC
            "-//Hibernate/Hibernate Configuration DTD//EN"
            "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
        <session-factory>
            <property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
        </session-factory>
    </hibernate-configuration>

dbConnection.properties

connection.driver_class=org.postgresql.Driver
connection.username=postgres
connection.password=postgres

And when creating the SessionFactory you can do the following.

Properties dbConnectionProperties = new Properties();
try {
    dbConnectionProperties.load(ClassLoader.getSystemClassLoader().getResourceAsStream("dbConnection.properties"));
} catch(Exception e) {
    // Log
}

SessionFactory sessionFactory = new Configuration().mergeProperties(dbConnectionProperties).configure().buildSessionFactory();
shazin
  • 21,379
  • 3
  • 54
  • 71
  • The `load` method of `dbConnectionProperties` cannot be of type `String`. IDE suggests: void load(Reader) OR void load(InputStream). How to fix it? – J.Olufsen Jun 12 '14 at 04:00
  • Thanks! Recently found another way of doing it. Why your solution is better than this: http://stackoverflow.com/questions/17939339/propertyplaceholderconfigurer-with-hibernate-cfg-xml ? – J.Olufsen Jun 12 '14 at 04:14
  • For future reference of anyone trying to implement this solution, you need to use `hibernate.connection.username` in the properties file (as well as for password and any other parameter that needs to be injected into the `` tag). – ygesher Sep 09 '17 at 22:02
5

Following this, this and this I came up with the following Maven configuration that replaces/filters placeholders from your hibernate.cfg.xml file with properties from a properties file:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <version>2.6</version>
            <executions>

                <execution>
                    <id>copy-resources</id>
                    <!-- here the phase you need -->
                    <phase>validate</phase>
                    <goals>
                        <goal>copy-resources</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${basedir}/target/extra-resources</outputDirectory>
                        <resources>
                            <resource>
                                <directory>src/main/resources</directory>
                                <filtering>true</filtering>
                            </resource>
                        </resources>
                    </configuration>
                </execution>
            </executions>

        </plugin>
    </plugins>

    <!-- Specify the file that contains the value to replace the placeholders -->
    <filters>
        <filter>src/main/resources/dbConnection.properties</filter>
    </filters>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <excludes>
                <exclude>*</exclude>
            </excludes>
            <includes>
                <include>hibernate.cfg.xml</include>
            </includes>
        </resource>
    </resources>
</build>

With this configuration, you can run the validate Maven goal to generate the filtered files and see if they are relpaced correctly

This is of course useful if you are using Maven.

Gabriel Ruiu
  • 2,753
  • 2
  • 19
  • 23