Yesterday I found myself in an interesting situation. I had to write a little utility to modify some I-Proving database records (the format of the name of blog entries and blog entry comments). I needed a standalone utility that would be able to access the database. I had to solve this in a unique way (for me anyway 🙂 and I decided I share the solution with everyone.
If this utility was to be run inside the app, then it would be fairly straightforward. The DAO was defined as a property of a service (the ContentService in this example) in the apps applicationContent.xml file. The service would be available to use because of the JBoss initial context when running in the JBoss app server. Once the app was up and running, all I’d have to do is get an instance of the service via the registry.
return (ContentService) Registry.getComponent(ContentService.class);
Then getting the DAO would be as simple as calling a get method on the service (spring would have provided the DAO for the service) or just using the service itself to query the database.
This utility had to be run as a standalone app. i.e. I wouldn’t be running JBoss, thus I wouldn’t have access to JBoss’s initial context, thus no service and no DAO access which would allow me to be able to use the DAO defined in the traditional applicationContent.xml file.
BC advised an adequate solution would be to define a customized spring.xml file, specifically for my utility. This file would be in the same package as the utility. In this custom spring file, I was to do the following things…1. Define the Datasource
<bean id="javax.sql.DataSource" class="com.mysql.jdbc.jdbc2.optional.MysqlDataSource"> <property name="url" value="jdbc:mysql://localhost:3306/db_name" /> <property name="user" value="the_user" /> <property name="password" value="the_password" /> </bean>
2. Define the Hibernate Session Factory for the Data SourceOf course I’d have to include any mapping files for the DAO(s) my utility was using.
<bean id="org.hibernate.SessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="javax.sql.DataSource" /> <property name="mappingResources"> <list> <value>ca/intelliware/sample/ContentImpl.hbm.xml</value> <value>ca/intelliware/sample/ContentAccessControl.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.max_fetch_depth">2</prop> </props> </property> </bean>
3. Define the DAO to use the Session factory
<bean id="ca.intelliware.sample.dao.ContentDAO" class="ca.intelliware.sample.dao.impl.ContentDAOImpl"> <property name="sessionFactory" ref="org.hibernate.SessionFactory" /> </bean>
4. Set the Utility’s context Now that I had my spring.xml configured, it was just a matter of hooking it up; this was the key step. To do so, I had to set my customized spring.xml as the context for my utility.
Registry.setContext(new XmlBeanFactory(new ClassPathResource("ca/intelliware/sample/spring.xml")));
5. Get an instance of the DAOOnce I did that, it was just a matter now of then calling on the registry to get me a instance of the ContenDAO.
return (ContentDAO) Registry.getComponent(ContentDAO.class);
Of course, this works only because this DAO now has a means of getting a session and data source as specified in the custom spring.xml. Then I just ran my utility as a Java app in Eclispe and bingo!