A sweet note from someone

I’ve been actually down lately. Just came back from a visit of a therapist. I could barely sleep the last few weeks.

I found this in my facebook inbox which cheered me up a little. Thank you!

hi… my name is *removed for privacy*. are you the girl who ran beautiful php scripts and webdesign like a decade ago or so??! i think that’s was when i was just about starting college, i stumbled onto your site, and really fell in love with the heart and soul you poured into your online creations!! you even had some personal projects with which i deeply identified. i fell out of webdesign for many years after that, but am trying to return back to it, and came upon ‘dodo’s scripts’, and all the memories i had of visiting your creations and your stories came into place… you struck a resonant chord within me back in those days, and i thank you for that :) i’m sorry to other you like this as a total stranger, but you had a memorable impact on me at that point :) :) i hope you are having a serene and blissful year thus far. yours truly, *removed for privacy*

In addition, my friend Leah, who used to be an admin @ my message board Dodo’s Message Board, created a DMB facebook group. If you use to belong to dodosmb.com or regretless.org or regretless.com/board, please join us :)

Spring loading properties from database with a twist

Watched the spring framework 3.1 webinar today and it was pretty interesting.

Anyway, at work we are trying to possibly load property values from a database to resolve some tension between the developers and system specialists.

I played a little bit at home as how we would set this up. This is not a new issue obviously; many have solved it previously. I did it partly as an exercise to familiarize myself with cygwin, maven and intellij as they are the new tools I will be using at my new job :)

The things to accomplish

  • Load properties to replace placeholders in spring config from both .properties file and a database table
  • The configuration table will contain properties for more than one application
  • Use another .properties file to initialize the datasource for the database configuration table.

Main libraries used

  • Spring (3.0.3.RELEASE)
  • H2 database (1.1.118)
  • Spring modules (0.8a)
  • Commons-configuration (1.6)
  • JUnit (4.5)
  • Spring-test (3.0.3.RELEASE)

I first created a simple project via maven. I assume you have maven installed with shell/batch access.

mvn archetype:generate -B -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.0 -DgroupId=net.pureessence -DartifactId=DatabaseConfiguration -Dversion=1.0 -Dpackage=net.pureessence.example

How I wired up the configuration datasource

I created a factory to create the datasource using org.apache.commons.dbcp.BasicDataSourceFactory.createDataSource(properties) and loaded the initial datasource properties statically via the class loader. For more information on the property keys used by BasicDataSourceFactory.createDataSource, visit this test case.

public static DataSource createDataSource(String propertyFilename) throws Exception {
    Properties properties = new Properties();
    InputStream in = PropertiesDataSourceFactory.class.getClassLoader().getResourceAsStream(propertyFilename);
    properties.load(in);
    in.close();

    return BasicDataSourceFactory.createDataSource(properties);
}
<bean id="dataSource" class="net.pureessence.example.PropertiesDataSourceFactory" factory-method="createDataSource">
    <constructor-arg type="java.lang.String" value="databaseForConfiguration.properties" />
</bean>

How I wired up the configuration

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
    p:location="classpath:env.properties"
    p:properties-ref="commonsConfigurationFactoryBean"/>

<bean id="commonsConfigurationFactoryBean" class="org.springmodules.commons.configuration.CommonsConfigurationFactoryBean">
    <constructor-arg ref="databaseConfiguration"/>
</bean>

<bean id="databaseConfiguration" class="org.apache.commons.configuration.DatabaseConfiguration">
    <constructor-arg type="javax.sql.DataSource" ref="dataSource"/>
    <constructor-arg name="table" value="configuration"/><!— configuration table name —>
    <constructor-arg name="nameColumn" value="application"/><!— name column —>
    <constructor-arg name="keyColumn" value="key"/><!— key column —>
    <constructor-arg name="valueColumn" value="value"/><!— value column —>
    <constructor-arg name="name">
    <util:constant static-field="net.pureessence.example.Constants.APPLICATION_ONE"/>
    </constructor-arg><!— name (specific configurations) —>
</bean>

<bean id="person" class="net.pureessence.example.Person"
    p:firstName="${first.name}"
    p:lastName="${last.name}"
    p:email="${email}"
    p:car="${car}" />

The property key “car” is loaded from env.properties while “first.name”, “last.name” and “email” properties are loaded from the database table.

Why it works

In order to load configuration/placeholders from a database table, the datasource has to be instaniated prior to the instaniation of all of the other beans with placeholders. The databsource factory creates the instance of the datasource via another properties file loaded outside of spring.

Note about the tests

The tests are set up to load the H2 database with the configuration table & data prior to the loading of the spring context in order for it to work.

Source code

It contains both intellij and eclipse project files. You should have the m2eclipse plugin for eclipse installed in order to pull down the jars in pom.xml.

»>Git Repository