tags:

views:

321

answers:

3

When using database migrations, I obviously want none of the DAOs to be usable before the migrations are run.

At the moment I'm declaring a lot of DAOs, all having a depends-on=databaseMigrator property. I find this troubling, especially since it's error prone.

Is there a more compact way of doing this?


Notes:

+3  A: 

I do this on application start-up. The schema version that the application requires is compiled into the application as part of the build process. It is also stored in the database and updated by the database migration scripts.

On application start-up, the app checks that the schema version in the database is what it expects and if not, aborts immediately with a clear error message.

In a normal Java program, this happens right at the start of the main method.

In a webapp, it's performed by the app's ServletContextListener and is the first thing it does when the servlet context is created.

That's saved my (apps') bacon several times.

Nat
Thanks for the answer. I was looking for a Spring solution since all my datasources are already declared there.
Robert Munteanu
I'm sure you could use Spring to implement this. Whether it actually helps in this case is another question.
Nat
Whether using Spring would help? It certainly does by keeping the data source definitions unitary and _not_ suprising the developer by adding components outside Spring.
Robert Munteanu
+1  A: 

You could try writing a class that implements the BeanFactoryPostProcessor interface to automatically register the dependencies for you:

Warning: This class has not been compiled.

public class DatabaseMigratorDependencyResolver implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        String[] beanNames = beanFactory.getBeanDefinitionNames();
        for (String beanName : beanNames) {
            BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);

            // Your job is here:
            // Feel free to make use of the methods available from the BeanDefinition class (http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/beans/factory/config/BeanDefinition.html)
            boolean isDependentOnDatabaseMigrator = ...;

            if (isDependentOnDatabaseMigrator) {
                beanFactory.registerDependentBean("databaseMigrator", beanName);
            }
        }
    }

}

You could then include a bean of this class alongside all your other beans.

<bean class="DatabaseMigratorDependencyResolver"/>

Spring will automatically run it before it starts initiating the rest of the beans.

Adam Paynter
Looks nice, thanks.
Robert Munteanu
Nobody liked my solution, so I'll pick yours as the answer. Thanks!
Robert Munteanu
A: 

I ended up creating a simple ForwardingDataSource class which appears in the context files as:

<bean id="dataSource" class="xxx.ForwardingDataSource" depends-on="databaseMigrator">
   <property name="delegate">
      <!-- real data source here -->
   </property>
</bean>

If find it less elegant than Adam Paynter's solution, but clearer.

Robert Munteanu