I recently established a new open source project http://sourceforge.net/projects/kauklahti/
Nowadays, JPA and Hibernate is the object-relational mapping standard. So it is quite stupid to write your own solution, right?
Well, we’ve been using Hibernate several years in different kinds of projects. We’ve seen solutions and problems from other vendors as well. Common problem is that complex class hierachies with many tables easily cause performance problems.
Inexperienced coders don’t check the actual SQL and only trust table generation tools. Even with best coders, we spend a lot of time with tuning fetching strategies and caching solutions. And then we might switch to custom SQL and JDBC in most complex queries. When this is done carefully, we get things right in the end.
In my opinion, this tuning and configuring takes too much time. I am not happy with the productivity of current JPA tools.
Furthermore, there are a lot of other “minor” problems. Lazy initializations and library-specific Collections are problems for a remote client and Swing applications. There are lot of library dependencies and we need exactly the correct versions (yes, there is Maven/Ivy, but still conflicts with application server classpath and other frameworks might cause a major headache). And I don’t like writing xml or annotations that make your code messy.
I wanted a simpler solution. I looked at couple of alternatives, but APIs weren’t exactly what I was looking for.
However, Spring framework has this simple class JdbcTemplate. It’s great with plain JDBC. Spring also includes BeanPropertyRowMapper that extracts ResultSet into list of JavaBeans. I liked the idea, but I also wanted some support for joined tables and full CRUD generation. I wrote Kauklahti to do just that.
How does it work? Supposing we have tables:
create table guitar ( id INTEGER PRIMARY KEY, name varchar(100)); create table guitarstring ( id INTEGER PRIMARY KEY, tone varchar(1), guitar_id INTEGER); alter table guitarstring add constraint string_guitar_id foreign key (guitar_id) references guitar (id);
We write Java classes:
public class Guitar {
private Long id;
private String name;
private List<GuitarString> strings;
public Guitar() {}
public Guitar(Long id, String name, List<GuitarString> strings) {
this.id = id;
this.name = name;
this.strings = strings;
}
}
public class GuitarString {
private Long id;
private String tone;
public GuitarString() { }
public GuitarString(Long id, String tone) {
this.id = id;
this.tone = tone;
}
}
Then we create table mapping:
Table guitarTable = new Table(Guitar.class, "GUITAR");
Column[] guitarCols = {
new Column("id", "id", true),
new Column("name", "name", false)
};
guitarTable.setColumns(guitarCols);
Table stringTable = new Table(GuitarString.class, "GUITARSTRING");
Column[] stringCols = {
new Column("id", "id", true),
new Column("tone", "tone", false)
};
stringTable.setColumns(stringCols);
Join stringJoin = new ChildRefJoin("strings", stringTable,
new String[] {"id"},
new String[] {"guitar_id"});
guitarTable.setJoins(new Join[] {stringJoin});
Or if you like convention over configuration, you may use AutoConfigurator to create Table-mappings:
AutoConfigurator autoConf = new AutoConfigurator("fi.devtrain.*");
Table table = autoConf.config(Guitar.class);
Now it’s simple to generate SQL:
GuitarString aString = new GuitarString(new Long(1), "A"); List<GuitarString> strings = new ArrayList<GuitarString>(); strings.add(aString); Guitar guitar = new Guitar(new Long(1), "Strato", strings); List<WriterResult> inserts = mapper.writeInsert(guitar,guitarTable); List<WriterResult> updates = mapper.writeUpdate(guitar,guitarTable); List<WriterResult> deletes = mapper.writeDelete(guitar,guitarTable);
Execute it with Spring JdbcTemplate:
JdbcTemplate jdbcTemplate = new JdbcTemplate(myDataSource);
for (WriterResult wr : inserts) {
jdbcTemplate.update(wr.getSql(), wr.getParams());
}
For queries, use Spring ResultSetExtractor with Kauklahti mapper.
ResultSetExtractor extr = new ResultSetExtractor() {
public Object extractData(ResultSet resultSet)
throws SQLException, DataAccessException {
return mapper.extract(resultSet, guitarTable);
}
};
String query = mapper.writeSelect(guitarTable);
List guitars = (List) jdbcTemplate.query(query, new Object[0],extr);
So what’s so great about Kauklahti? I wrote the solution, because it only took about 1300 LOC. And because:
- Mapping API is simple and programmatic
- Every piece of SQL is in my hands before execution
- It provides basic features I need in ORM (and nothing more)
- Only log4j.jar is required library dependency (even Spring is optional)
If you’re interested, download latest release from SourceForge or check out the code from http://kauklahti.svn.sourceforge.net/svnroot/kauklahti
User’s Guide and test examples are included to get things started.

23 comments
Comments feed for this article
October 20, 2009 at 2:25 am
Andrew D Wolfe Jr
Tomi – looks nice and sweet.
You are completely right that inexperienced coders only trust the table generators. Actually, I worked in a LISP shop where seasoned 40-something hackers only trusted the table generator too!
I think that the trouble comes when you have to scale the schema, maintain the schema, or both.
I love “hello, world,” but it’s not a good test for a database schema. Everything else in an application disappears when the user session ends, and typically that’s when the coder’s attention span ends too. The data attached to the user needs to be good six months or six years later. I’m the guy who gets the call when the customer has data corruption arising from a programming error. It isn’t a nice place to be, so I made a specialty of preventing it. ORMs are a wildly overrated obstruction to my work.
Keep reporting your travels candidly!
Best,
Andrew Wolfe
October 20, 2009 at 4:52 pm
Stefan Lecho
Any idea on how this solution compares to Apache Empire-db (http://incubator.apache.org/empire-db/index.html) ?
October 20, 2009 at 5:16 pm
Tomi Tuomainen
Apache Empire API seems a bit different (after quick look at the tutorial). In Kauklahti there is no config.xml (or any xml at all).
Kauklahti provides AutoConfigurator if you prefer convention over configuration.
Kauklahti does not provide any objects to execute SQL (like DBCommand). Kauklahti integrates to JdbcTemplate or plain JDBC. It just writes SQL and extracts ResultSets.
When using Kauklahti you modify JavaBeans directly, DBRecord seems a bit clumsy to me.
Empire seems to have three options to handle query result. But it does not automatically convert ResultSet into objects in class hierarchy? That seems like a shortcoming.
But I don’t have hands-on have experience on this Apache project, so I really don’t know its strengths.
October 22, 2009 at 7:05 pm
Nicola
Tomi
how this solution compares to EOD sqL https://eodsql.dev.java.net/ , Hibernate is a mesh…so many dependency, etc..
October 22, 2009 at 10:03 pm
Tomi Tuomainen
It seems (after quick look at the example code) that you write sql in eodsql BaseQuery class. And then use annotations in data object to connect to columns.
Kauklahti generates you SQL. You just write JavaBeans with attributes and define mapping rules via external class (Table or AutoConfigurator, but no annotations).
Kauklahti extracts ResultSet into class hierarchy with Collections and nested objects. I don’t think eodsql supports this.
If I got the eodsql idea right, it is more like a convenient JDBC API. Kauklahti is more like “ORM” by supporting joins and class hierarchy. I didn’t want to reinvent wheel of nice JDBC API, because Spring JdbcTemplate does the perfect job.
November 18, 2009 at 7:08 pm
Jason Morris
EoD SQL will return any type you want out:
@Select(“SELECT * FROM users WHERE id = ?{1}”)
User selectUserById(int id);
@Select(“SELECT * FROM users WHERE age = ?{1}”)
List selectUsersByAge(int age);
You have many other options as well, including DataSets which are Lists that lazy-load their content.
October 22, 2009 at 8:04 pm
Remco
How does this compare to iBatis? (except from the no xml, i like!)
October 22, 2009 at 10:14 pm
Tomi Tuomainen
IBatis is a full-blown ORM. It handles database connections, sessions, transactions etc.
Kauklahti just generates SQL. And converts ResultSet into hierarchy of Objects. In the end, it does pretty much the same thing as IBatis or any other “real” ORM tool. But O would say that Kauklahti is the simplest possible ORM supporting joins and class hierarchies. It’s up to you, if you want to execute SQL with Spring, basic JDBC or some other tool.
October 23, 2009 at 5:02 am
pcopeland
We’ve had lots of success with Apache Cayenne (http://cayenne.apache.org/). Its provides a clean and reasonably simple ORM layer that is very performant. We avoid much of the caching and simply use it to move data in and out of SQL backends. It also comes with a nice graphical modeling tool that is easy to use.
October 23, 2009 at 10:39 am
Sathish K
This framework is really simple. I like it. Good work Tomi !!!
The only concern I have is the name. Can you tell me how to pronounce it :) I would suggest easier names like “Kalauti” or “KalORM” or “Ruju”(means simple).
October 23, 2009 at 8:40 pm
Tomi Tuomainen
Thanks Sathish.
Kauklahti is a small train station near here. It is quite small with simple and clean architecture. I am not going to even try to teach you how to pronounce that Finnish word :)
I know that Kauklahti is hard to google and does not sound very sexy. But if you guys really start using this worldwide, I might consider a naming contest :)
But I have some doubts, if I’m getting my message through. People are quite aggressive in TSS posts . And there are no fans of the framework in SourceForge either (thumbs up reviews, please!).
But at least this framework is helping my job. And we’ve created some conversation in the community.
October 28, 2009 at 9:43 am
manany
Hey Tomi,
I hope you don’t mind the aggressive feedback at TSS. That’s typical human reaction against anything new.
I have not tried Kauklahti – yet. However, I consider most ORM solutions for Java a major pain in the.. head; and if Kauklahti promises simplicity, that warrants that I give it a try.
Final hint is that if I were you I’d try to find some wants/needs that major ORMs such as Hibernate or iBatis do not fulfill (Plain simplicity is just great for a start).
Keep up the spirit and the good work :)
October 27, 2009 at 10:52 pm
Henry Katz
Hi,
Do you have any examples illustrating a many-to-many join?
Thanks,
Henry
October 28, 2009 at 12:41 am
Tomi Tuomainen
I just added TestManyToMany in SVN: https://kauklahti.svn.sourceforge.net/svnroot/kauklahti
Also, check doc/faq.html for brief descrption (How do I handle many to many relationships?).
October 28, 2009 at 12:56 am
Jeff Johnston
On our project we have slowly been using less and less Hibernate and now only use it for basic create, update, and delete operations. I have been disenchanted with ORM for quite some time and what you did looks like something I wish I would have thought to do a long time ago. Really nicely done!
At first I did not get what your framework was about. Then I tried a test with our application and now I see why you did it. Its like you moved the JPA annotations from the classes and then configure things in one place. So from a code standpoint it is about the same amount of work. Then the real power is that you can take that configuration and it generates all the SQL statements. That is very refreshing to see! It reminds me of how good it felt to write SQL again for pulling the data. Having the statements in such a raw format makes it so easy to debug.
I am going to pitch to the other developers tomorrow that we try this framework out. Can you tell us anything that you feel is still missing, or something you wish was a little better? We are more than willing (and able) to help out, but I thought I would get your take.
I saw your post on theserverside.com…you kind of took a beating and did not deserve any of that! Here are some articles that really support what you are doing that I thought were interesting. Especially the part about what a lot developers really want is just a SQL statement generator for basic crud work…which is what you have.
http://codemonkeyism.com/orms/
http://www.hatfulofhollow.com/posts/code/farewell-to-orms.html
P.S. I also like the name…only after I found out where you got it from. I wouldn’t change it!
October 28, 2009 at 10:32 am
Tomi Tuomainen
We are currently using Kauklahti in a real project. But as we all know, ORM is not an easy task. Therefore, I assume there might be some issues we face with composite keys etc. (But the code is clean and easy to fix.)
Many-to-many mapping is not that intuitive right now. I will think about if it is possible to implement this in a simpler way. However, I would like to stick to one class per table strategy anyway.
Currently I am coding a nice feature, that writes create table -statements based on Table-objects. With AutoConfigured JavaBean and HSQLDB, it is a kind of object database :) The real use is for unit testing. In development we may generate in-memory database and use it. In test environment we would use the same Table-mappings for a remote Oracle database.
October 28, 2009 at 1:43 am
Thierry Uriot
Thank you for this new tool (I also remember TikeSwing) which confirms the tendency towards simplicity amongst some Java developers : Tomcat (vs weblogic), apache Click, H2 database, Activemq, Ivy, Jersey … While big frameworks force us to compel, lighter ones can be tailored to our needs.
October 28, 2009 at 2:10 am
Matt Beale
Lovin your work! I’ll definitely be putting it through the paces with some of my home projects!
I don’t know if you’ve heard of apache click but they too are people who are sick of the nightmare of overly complex frameworks… but your two projects fit like a glove!
October 28, 2009 at 4:28 am
Henry Katz
Hi,
Thanks for quick update. Now to see how this may play a role within Seam framework.
I wasn’t aware guitars were so popular up there ;-)
Henry
October 28, 2009 at 7:37 am
JT
Simple framework, good job! One comment though, assuming that the mappings between table’s columns and object’s attributes are not straightforward, I have to write the codes for that?
Even with the convention over the configuration, one has to write (2 lines) codes. Why not just create a spring bean and handle it in at the spring level? No codes is better than two :)
October 28, 2009 at 10:48 am
Tomi Tuomainen
Thanks JT.
I have been trying to avoid direct dependency with Spring. Although, probably everybody use it with my framework, Kauklahti does not depend on any particular Spring version (which is nice).
You have to tell somehow anyway, what is the column name for each field (if not the same). I don’t know if handling this in Spring level would be any better than just coding it to Kauklahti Column. The goal of the framework is to avoid xml/annotation configuration and just code the solution.
But could you provide an example of how this would be handled in Spring level? I could perhaps see, the possible advantage of this approach.
October 28, 2009 at 12:40 pm
Matt Beale
The goal of the framework is to avoid xml/annotation configuration and just code the solution.
I agree with that goal. Let in Spring / XML and you’re back at hibernate right? ;) And I’m happy not having to debug proxy problems
November 23, 2009 at 10:49 am
An Object Graph Pattern « Travelog of Software Development
[...] have used this pattern with Hibernate. And if you have read about Kauklahti, you probably guessed by now, that it supports this pattern. All you need to do is implement [...]