null

NullPointerException, probably…

Posts Tagged ‘mongodb

Integrating MongoDB with Spring

with one comment

Apparently, most of the visitors to my “Integrating MongoDB with Spring Batch” post can’t find what they look for, because they look for instructions how to integrate MongoDB with plain Spring Core.
Well, the source includes that integration, but it’s on github, and anyway that wasn’t the focus of that post.
So, here’s the integration – short, plain and simple:

  • Properties file with server and database details (resides in classpath in this example):
1    db.host=localhost
2    db.port=27017
3    app.db.name=app
  1. application-config.xml (or whatever you call it):
    1<beans xmlns="http://www.springframework.org/schema/beans"
    2       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3       xmlns:context="http://www.springframework.org/schema/context"
    4       xsi:schemaLocation="http://www.springframework.org/schema/beans
    5           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    6           http://www.springframework.org/schema/context
    7           http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    8    <context:property-placeholder 
    9                location="classpath:db.properties"/>
    10    <bean id="mongo" class="com.mongodb.Mongo">
    11       <constructor-arg value="${db.host}"/>
    12       <constructor-arg value="${db.port}"/>
    13   </bean>
    14   <bean id="db" 
    15      class="com.mongodb.spring.config.DbFactoryBean">
    16       <property name="mongo" ref="mongo"/>
    17       <property name="name" value="${app.db.name}"/>
    18   </bean>
    19</beans>
  2. The com.mongodb.spring.config.DbFactoryBean class:
    1 public class DbFactoryBean implements FactoryBean<DB> {
    2    
    3        private Mongo mongo;
    4        private String name;
    5    
    6        @Override
    7        public DB getObject() throws Exception {
    8            return mongo.getDB(name);
    9        }
    10   
    11       @Override
    12       public Class<?> getObjectType() {
    13           return DB.class;
    14       }
    15   
    16       @Override
    17       public boolean isSingleton() {
    18           return true;
    19       }
    20   
    21       public void setMongo(Mongo mongo) {
    22           this.mongo = mongo;
    23       }
    24   
    25       public void setName(String name) {
    26           this.name = name;
    27       }
    28 }
    
1    @Configuration
2    public class ApplicationConfiguration {
3    
4        @Value("${app.db.name}")
5        private String appDbName;
6    
7        @Value("${db.host}")
8        private String dbHost;
9    
10       @Value("${db.port}")
11       private int dbPort;
12   
13   
14       @Bean
15       public DB db() throws UnknownHostException {
16           return mongo().getDB(appDbName);
17       }
18   
19       @Bean
20       public Mongo mongo() throws UnknownHostException {
21           return new Mongo(dbHost, dbPort);
22       }
23   }

That’s, actually, it – enjoy. If you feel some part of the puzzle is missing, please leave a comment.

Written by JBaruch

30/05/2010 at 16:25

Posted in Frameworks, Friendly Java Blogs

Tagged with , ,

Integrating MongoDB with Spring Batch

with 4 comments

Update (May 30th 2010):
If you look for plain core Spring integration with MongoDBhere’s a post for you.

Spring Batch is a superb batch framework from, well, Spring. It covers all the concepts of batch architecture and, generally, spares you from reinventing the wheel. It’s cool, really. If you have batch-oriented application, you must go and take a look at Spring Batch. And if you don’t know what batch-oriented application is, just think about reading-validating-saving-to-db a zillion text files every night, unattended. Now you know what batch-oriented application is, go and look at Spring Batch.

Welcome back. As you’ve seen, Spring Batch constantly saves its state in order to be able to recover/restart exactly when it stopped. JobRepository is the bean in charge of saving the state, and its sole implementation uses data access objects layer, which currently has two implementations – in-memory maps and JDBC. It looks like this:

JobRepository class diagram

Of course, the maps are for losers testing,  JDBC implementation is the one to use in your production environment, since you have RDBMS at your application anyway, right? Or not…

Today, when NoSQL is gaining momentum (justified, if you ask me) the assumption that  “you always have RDBMS in enterprise application” is not true anymore. So, how can you work with Spring Batch now? Using in-memory DAOs? Not good enough. Installing, setting up, maintaining, baby-sitting RDBMS only for Spring Batch meta-data? Hum, you’d rather not. There is a great solution – just keep the meta-data in the NoSQL database you use for the application itself. Thanks to Spring, the Spring Batch architecture is modularized and loosely-coupled, and all you have to do in order to make it work is to re-implement the four DAOs.

So, here’s the plan:

  • Implement *Dao with NoSqlDb*Dao
  • Add them to Spring application context
  • Create new SimpleJobRepository, injecting your new NoSqlDb DAOs into it
  • Use it instead of the one you would create from JobRepositoryFactoryBean
  • Profit

That was exactly what I did for our customer, implementing the DAOs using MongoDB. Guess what, you must go and take a look at MongoDB.  It’s lightning-fast, schema-less document-oriented database, that kicks ass. When you suddenly have a strange feeling that RDBMS might not be the best solution for whatever you do, chances are you’d love MongoDB, as I do now. There are use-cases, in which you just can’t implement whatever you need to do with relational storage. Well, I lied. You can. It will take a year, it will look ugly and perform even worse. That’s my case, and I am just happy the year is 2010 and we know by now that one size doesn’t fit all.

I have to admit -implementing Spring Batch DAOs with MongoDB was fun. Even Spring Batch meta-data model, which was designed with relational storage in mind, persists nicely in MongoDB. Should I even mention that the code is cleaner comparing to JDBC? Even on top of JDBC template?

Now go and grab the Spring Batch over MongoDB implementation and the reference configuration: http://github.com/jbaruch/springbatch-over-mongodb. I have used the samples and the tests from original Spring Batch distribution, trying to make as few changes as necessary. You’ll need MongoDB build for your platform and Gradle 0.9p1 to build and run. (Why Gradle? Because it is truly a better way to build).

If you use MongoDB – enjoy the implementation as is. If you use some other document-oriented DB, the conversion should be straightforward. In any case, I’ll be glad to hear your feedback.

Written by JBaruch

27/04/2010 at 15:10

Follow

Get every new post delivered to your Inbox.

Join 1,067 other followers