Wednesday, May 13, 2009

JPA2 - the potential to revolutionize Java development?

innovation.jpg 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.

According to spec lead Linda Michiel's Blog:
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).

Emmanuel Bernard (founder of Hibernate Search, spec lead of JSR 303) comments on Linda Michiel's Blog:
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.

So I guess it would be an appropriate moment to look into the javax.annotation.processing package of JDK 6.

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

revolution.jpg 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 ...

Update: There is even more Information on Gavins Blog: Java 6 compiler plugins and typesafe criteria queries and Linda blogs the typesafe query API for JPA 2.0

10 comments:

  1. Awesome news for those of us tired of a second class query language inside mangled, type-unsafe annotations with no tool support. I want JPA2 today!

    ReplyDelete
  2. I agree with the following comment found on one of the posts .. can we do what Thomas is saying here. It certainly would help on the verbosity.


    The syntax is still a bit verbose:

    q.where(qb.equal(c.get(ContactInfo_.address).get(Address_.zipcode), "95054"),
    qb.equal(p.get(Phone_.phoneType), PhoneType.OFFICE))
    .select(p.get(Phone_.billedTo)).distinct(true);

    I hope this can be simplified to:

    q.where(ContactInfo_.address.zipcode).eq("95054").
    and(Phone_.phoneType).eq(PhoneType.OFFICE).
    selectDistinct(Phone_.billedTo);

    ReplyDelete
  3. Dreamsource ORM provides the simplest dynamic query as indicated by the following code:

    Select<Person> select = new Select<Person>(Person.class, true);
    select.from(personTable);
    select.where(personTable.getLastName().startsWith("M"));
    select.fetchRange(5, 4);
    select.orderBy(personTable.getLastName(), personTable.getFirstName());
    List<Person> persons2 = entityManager.list(select);


    Please see
    http://code.google.com/p/dreamsource-orm/ for more information.

    ReplyDelete
  4. 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.

    Nothing revolutionary. Move on

    ReplyDelete
  5. @Anonymous

    If you actually read my article, then you would have noticed that in my opion the revolutionary concept is not the Metamodel API itself.

    I think the idea to use the javax.annotation.processing package of JDK 6 to seamlessly integrate the code-generation process into the compilation step has a lot of potential.

    This is similar to the new AST-Transformations in Groovy 1.6.

    This opens the world of compile-time metaprogramming ... definitely a hot topic!

    ReplyDelete
  6. Compile-time post-processing (JDK1.6) has also already been done before ... e.g bytecode enhancement for some JDO implementations. JPA2 proposes using it, great, but nothing specific to them.

    ReplyDelete
  7. I am using LiquidForm and really like it from a syntax pov.

    -> http://code.google.com/p/liquidform/

    ReplyDelete
  8. I have a few concerns about the static metadata model:

    - 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.

    The code would look like:
    ProxyQueryFactory queryFactory = ProxyQueries.createFactory(entityManager);
    ProxyQuery<Customer> query = queryFactory.createQuery(Customer.class);
    Customer a = query.getRootProxy();

    query.andWhere(a.getFirstName()).equalTo("John");

    List<Customer> results = query.select().find();

    // jpql produced: select a from Customer a where a.firstName = :p1

    This would be akin to mock object techniques where a method calls are invoked a proxy for a class and the resulting calls are recorded.

    I’ve made a somewhat complete prototype at:
    https://www.cementframework.org/repos/pub/querybyproxy/trunk/
    (I'm just about to add raw hibernate support, jpa is already supported)

    ReplyDelete
  9. This comment has been removed by the author.

    ReplyDelete
  10. I just posted a comparison of Querydsl and the JPA 2 Criteria API here :
    Querydsl as an alternative to the JPA 2 Criteria API

    ReplyDelete

Related Posts Plugin for WordPress, Blogger...