I am thrilled to announce first version of my Spring Data JDBC repository project. The purpose of this open source library is to provide generic, lightweight and easy to use DAO implementation for relational databases based on JdbcTemplate from Spring framework, compatible with Spring Data umbrella of projects.

Design objectivesLightweight, fast and low-overhead. Only a handful of classes, no XML, annotations, reflectionThis is not full-blown ORM. No relationship handling, lazy loading, dirty checking, cachingCRUD implemented in secondsFor small applications where JPA is an overkillUse when simplicity is needed or when future migration e.g. to JPA is consideredMinimalistic support for database dialect differences (e.g. transparent paging of results)
Features
Each DAO provides built-in support for:

Spring 3.1 introduced great caching abstraction layer. Finally we can abandon all home-grown aspects, decorators and code polluting our business logic related to caching. Since then we can simply annotate heavyweight methods and let Spring and AOP machinery do the work:

@Cacheable("books")
public Book findBook(ISBN isbn) {...}
"books" is a cache name, isbn parameter becomes cache key and returned Book object will be placed under that key. The meaning of cache name is dependant on the underlying cache manager (EhCache, concurrent map, etc.) - Spring makes it easy to plug different caching providers. But this post won't be about caching feature in Spring...

Some time ago my teammate was optimizing quite low-level code and discovered an opportunity for caching. He quickly applied @Cacheable just to discover that the code performed worse then it used to. He got rid of the annotation and implemented caching himself manually, using good old java.util.ConcurrentHashMap…

This is one of these very simple programming puzzles I came across recently:

given a function returning random integers from 0 to 4 inclusive with equal probability, write a function returning random integers from 0 to 6 inclusive.
Of course the solution should also return equally distributed numbers. So let’s start from an input function sample definition:

def rand4() = (math.random * 5).toInt
Your task is to implement rand6() by only using rand4(). Give yourself few minutes and continue reading.

.

.

.

The first approach is pretty straightforward but happens to be completely broken: