Thanks krishy for this insight.
And indeed, I have split the hibernate configuration in two files, but not exactly in the way you suggest. Primarily, because, as I'm using annotation based persistence, there are no class specific mapping files. But also thanks to the fact I'm using Spring.
Thus, in a first bean configuration file, which is database agnostic, I declare a sessionfactory listing the persistent classes, and a set of DAO service implementations handling these classes as follows :
Code:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="hibernateProperties">
<ref bean="hibernateProperties"/>
</property>
<property name="annotatedClasses">
<list>
<value>com.example.dao.entities.MyFirstEntity</value>
<value>com.example.dao.entities.MySecondEntity</value>
...
</list>
</property>
</bean>
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
<bean id="myFirstEntityService" class="com.example.dao.services.MyFirstEntityServiceImpl">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="mySecondEntityService" class="com.example.daos.ervices.MySecondEntityServiceImpl">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
As you'll notice, this file contains references to two external beans :
myDataSource and
hibernateProperties. These beans are defined in a separate XML file, and, their content depends on the actual configuration of the database access. As an example, here's how they are defined when running unit tests, in one of the project modules :
Code:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="hibernateProperties" class="java.util.Properties">
<constructor-arg>
<props>
<prop key="hibernate.connection.driver_class">org.hsqldb.jdbcDriver</prop>
<prop key="hibernate.connection.url">jdbc:hsqldb:file:/tmp/daotest</prop>
<prop key="hibernate.connection.username">sa</prop>
<prop key="hibernate.connection.password"></prop>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
<prop key="show_sql">true</prop>
</props>
</constructor-arg>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties">
<ref bean="hibernateProperties"/>
</property>
</bean>
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${hibernate.connection.driver_class}" />
<property name="url" value="${hibernate.connection.url}" />
<property name="username" value="${hibernate.connection.username}" />
<property name="password" value="${hibernate.connection.password}" />
</bean>
</beans>
I tried using a Spring
<import resource="..."> statement to include the second file in the first one, but as the arguments of these statements are relative to the location of the importing file this wouldn't work in all scenarios (such as when the filename of the XML file with the connection characteristics is given with a command-line argument). So I adapted my applications to make them load the two files, either in the same Spring XmlApplicationContext if both are located in the classpath, or in two different XmlApplicationContexts if they come from different sources.
As you can see, it was quite an investment (and, granted, it has become more of a Spring topic rather that a Hibernate one) but I've got the feeling that it's starting to pay off.
Cheers,
MmM