Wednesday, May 13, 2009

JPA2 - the potential to revolutionize Java development?

The proposed final draft of JPA2 (JSR 317) is out for more than a month now.

Between the public review version and the proposed final draft, a significant detail was added. This detail might well be overlooked, but in my opinion it has the potential to revolutionize Java development.

I am talking about the JPA Metamodel API.

With the new Metamodel API, queries can become almost completely typesafe. This is achieved by exposing a typesafe metamodel of the entity model.

This metamodel is actually nothing fancy, it is represented as simple annotated Java classes (ups... I might just have lost all the heavyweight MDSD guys ;-))

Now, the usage of Java classes with public static fields to get typesafety is hardly something new. I have been on several project that successfully leverage this.

Of course it makes sense to generate those classes. Therefore most of the projects using this concept have developed some homegrown generator infrastructure. This is usually where the problems start... this infrastructure is mostly proprietary, can be clumsy or outdated, needs special instructions and intricate knowhow. It can and therefore will fail, it interrupts the build process and prevents a seamless development experience (Of course thats just my point of view :-))

That's exactly where the revolutionary potential of the proposed implementation of the new JPA Metamodel API kicks in.

We plan to release an annotation processor to be run in conjunction with javac to generate these classes.

Gavin King (founder of Hibernate and Seam, spec lead of JSR 299) was the originator of the idea for this typesafe Metamodel API. On his blog he presents the idea to realize the code generation process as an APT plugin for javac:

So I've just spent several days researching the capabilities of javac Processors, and it's very clear that you can generate the necessary types as part of the compilation process. So no tool will be required. (This is a very exciting new language feature of Java 6, by the way).

Note that while the IDE can explicitly generate the metamodel on the fly, it can also delegate to the annotation processor that is triggered by the Java compiler. Even if the IDE has no specific JPA plugin, the metamodel is still generated on the fly. Same for plain old command line compilation.

As readers of my blog might have noticed, I am not the biggest fan of code generation.
But the above quotes sparked my interest, especially since they come from two bright minds that seem to have a sane opinion in the religulous debate of code generation.

As others have noted, the typesafe Metamodel API helps Java to catch up to LINQ in .NET.

But I think it has more potential!
If the generation process is really seamlessly integrated into the compilation process, then this could offer the means to overcome a lot of the deficiencies of the Java language.
Specifically areas where the lack of method and field literals prevents elegant solutions can now be tackled.
By extending the compilation process, its may even be possible to venture into areas where traditionally dynamically typed languages are especially strong ...

Calm down. I don't see how having a type-safe query of model classes would be in the category of "revolutionlizing". There are other DSLs that already do all of that, now. e.g QueryDSL from MySema. Having the "_" classes is ugly IMHO, and better would be to get language improvements in and have a real type-safe query language. It doesn't catch up with LINQ without that; this is a simple half-way house solution.

- Probably won’t survive refactoring well (unless refactoring the entity’s field would refactor the static metadata class’s field *usages*).

- Technique is jpa specific; for example if strongly-typed xpath is implemented, will that implementation’s static metadata model have two _’s in the class name? Does the technique even work with raw hibernate (the metadata classes are javax.jpa.metamodel)? Also, the metaclass could not be able to be used in other places with strings are currently used (e.g. apache’s BeanComparator).

I would propose a more integrated approach of invoking methods on a proxy instance to form path expressions (instead accessing fields on a static metadata model). This would be strongly typed, would work with both jpa and hibernate (and potentially with other criteria use cases). Because it uses normal java syntax, no additional tool support would be needed.