We have an application we would like to rewrite and move into JBoss. Among the things that need rework is the way we obtain connections to the database. For various reasons having to due to access control policies, our database password information is held in an external file accessible only to the application's user ID. Since the current application is stand-alone, this is not a problem. The password can and does change while the application is running.
We began reworking parts of the application to use Hibernate and managed to piece together something which works with this password arrangement. The classes we wrote are a DataSource implementation which extends oracle.jdbc.pool.OracleDataSource by adding a password lookup prior to asking for a connection. The external application that can change the password and our DataSource both lock the password file so that it is not possible for the password to be changed while the connection is being established and similarly, it is not possible to establish a connection while the password is being changed. Since password changes, while routine, are infrequent and the stall is short, this works for us.
Because our normal deployment process is to move our code from the development host to a QA/test host, then to a preproduction host, and finally to the production host, the actual connection parameters are all parameterized via an external property file. The way we did this was to have a hibernate.cfg.xml that looks something like this:
Code:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.provider_class">some.pkg.MyConnectionProvider</property>
<property name="connection.bean_name">myDataSource</property>
<!-- other configuration omitted -->
</session-factory>
</hibernate-configuration>
The use of connection.bean_name allows us to use Spring to inject the actual implementation class at run time. That isn't a strict requirement for us, but is convenient in that it allows us to use a lightweight database for developer testing to avoid conflicts with a shared development database. For example, the product database is Oracle, but I often use PostgreSQL on my laptop when working remotely. The Spring configuration for Oracle like this:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="myDataSource" class="some.pkg.MyDataSource">
<property name="URL"
value="jdbc:oracle:thin:@(description=(address_list=
(address=(host=${db1.server})(protocol=tcp)(port=${db1.port}))
(address=(host=${db2.server})(protocol=tcp)(port=${db2.port}))
(load_balance=yes)(failover=yes))
(connect_data=(service_name=${db.name}.example.com)))" />
<property name="databaseName" value="${db.name}" />
<property name="user" value="${db.user}"/>
</bean>
</beans>
We have a SpringUtil class that substitutes all the ${property} values when configure() is called. As I said, the above is not strictly required.
The big question that has me stumped at this point, is what do I need to implement in order to intercept connection creation and do the password lookup like I do now? I'm reading dire warnings about implementing my own DataSource in JBoss, but it seems like that is exactly what I have to do, just like I did before. Apart from the Sping stuff, should I be able to keep my setup of using a connection provider in the hibernate.cfg.xml and have it call my custom DataSource? Can someone point to the appropriate place to RTFM are welcome.
TIA,
roland