Tuesday, 15 June 2010

Querydsl vs JPA 2.0 Criteria API: First-round knockout

DISCLAIMER: I am not affiliated with the Querydsl team in any way, shape or form.

I've been developing with JPA on and off for a while now, only on small projects, but enough to be comfortable with it. 

Like everyone else, I soon reached the point where I thought "ergh, I don't much like embedding strings in my code to query my objects". @NamedQueries get checked a little, but not enough. I've been hit with build errors from my Hudson build server that my IDE (Eclipse, of course) doesn't notice and found the approach little better than embedding SQL strings. I'd also worked a little with LINQ in .NET and liked what I saw. I'm holding my breath for lambda functions in JDK 7, but to be honest, I'm feeling a bit light-headed and my face has gone purple.

So I came to the Criteria API that comes with JPA 2.0. Hey! That looks good. It's not LINQ, bit it looks like it'll do what I want. Typesafe queries. IDE code-completion. Nice. That's going to make my life easier and better.

Can you see where we are going readers? Yes? Yes. That's right. Then I tried to use it. OK "select p from Pet p" is easy. But it takes 5 lines of code. I have to create a CriteriaBuilder. Then a CriteriaQuery. Then a Root. Then a TypedQuery. Only then can I get the results. 

Now, let's be clear. I can write SQL. I'be been writing SQL for 15 years. I know how to write SQL to get the results I need in the majority of situations (and believe me, I've been tempted to do just that). My first non-trivial CriteriaQuery with the JPA Criteria API was to create a report joining a handful of tables, selecting a couple of attributes from each of those tables. I can do this with SQL. It's simple. I can't do it with the Criteria API. I'm NOT saying it's impossible. I'm sure it is possible. I'm sure it's easy, when you know how. But I don't know how, and for the life of me I can't find straightforward documentation or examples that explain clearly how to do this. So I leave it and go and do something else. Then I come back to it. What is that code? What does it mean? What does it do? I thought this was supposed to be better?

I didn't want to veer away from the standard API. I like standards. I prefer to work with APIs that are widely used, that have a common experience base. It makes life easier. But I kept seeing Querydsl (http://source.mysema.com/display/querydsl/Querydsl) mentioned. I think I'd noticed it before when looking into LINQ equivalents for Java. But  thought it looked a little too green for my taste, too much vaporware potential. So I kept away. But out of frustration, I came back. Hey! They have current activity. They have frequent releases. They have documentation... with examples. They have snippets for my POM (subliminalUSE MAVEN). The code ...looks...readable! I can understand at a glance what its doing! This can't be right. It won't work when I try it. 

So I try it. Hang on. It works! I can replace 5 opaque lines with 3 transparent ones! Let's try my report query... Wait... It's easy! I can read the code! It makes sense! It produces the SQL I expect! 

Ok. Job done. Criteria API in the bin. Querydsl in my holster. No contest. 

If you are using JPA and want to write typesafe queries in an IDE, then stop using the JPA 2.0 Criteria API and start using Querydsl. Today. 

If you work on the Criteria API team, get someone who's never used it to try to figure it out for themselves. Then, take them out for a beer and say sorry to them. Then hire the Querydsl team. 

P.S. Querydsl team - change the name. It's rubbish ;-)