Sunday, October 02, 2011

JPA 2 is the only part of Java EE 6 that I like a lot - how it compares to ActiveRecord

First, in Ruby-land: I am a huge fan of both Datamapper and ActiveRecord. Here I am only going to talk about ActiveRecord because it is freshest for me because I have been reading through a few Rails specific books that Obie Fernandez's publisher Addison-Wesley sent me review copies of earlier this year: these books use ActiveRecord 3.*. Recently I created two small throw-away learning apps using Rails 3.1 to kick the tires on new features and I used ActiveRecord for each.

One of my customers is a Java EE 6 shop (although we now do use SmartGWT for web apps) and I have been using JPA 2 (Hibernate provider) a lot. In Java-land, I can't imagine using anything else to access relational databases unless you want to use the Hibernate APIs directly, and I would not be inclined to walk that path.

I used to approach object modeling and design differently in Ruby: I would usually start with a relational database and use ActiveRecord's (fairly) automatically generated wrapping APIs. I now think that this is a generally "less good" approach (unless you are using a large legacy database) and now I start with generating models and migrations for the first cut of my object models and then use new migrations to manage changes to my models' schemas. Perhaps a small difference, but I am happier thinking about Ruby model classes than database schema.

So, my development approach is now very similar to using Ruby+ActiveRecord and Java+JPA 2.

My belief is that it is much faster to do object modeling and data persistence, including time for changing object models and associated business logic in Ruby and ActiveRecord. Not even the most die-hard Java developers should seriously argue with this. Given more expensive development in Java + JPA 2, I think that it is worthwhile listing some things I like less about ActiveRecord:
  1. It is more difficult to read code and understand the models because access methods are not defined in the code. For example, if a class User has a many to many relationship with the class Project, evaluating something like (User.first.public_methods - Object.methods).sort will indeed show that ActiveRecord provides a method projects that returns an array off associated projects. However, if you don't know the conventions that ActiveRecord uses for inherited class methods like has_and_belongs_to_many, has_many, belongs_to, etc. then reading other people's code may be confusing. I find that navigating large numbers of JPA annotated model classes in a good IDE like IntelliJ is quick and makes understanding a very large codebase manageable.
  2. A quick 100 hour reading of the Hibernate Reference Manual shows more capability and options than I am aware of in ActiveRecord.
  3. For large "enterprise" applications where increased cost of development does not matter as much, the availability of off shelf distributed caching options and other highly scalable infrastructure components favors, in my opinion, the Java platform.
That said, valid counter arguments are:
  1. The learning curve for ActiveRecord is relatively small so after writing a few complete web applications a developer will know most of what they need and well written Rails apps should be easy to read and understand. I also find that reading though large Rails applications using RubyMine provides almost as good of a developer experience as working with large Java projects with IntelliJ.
  2. Most Java developers will never need to use most of what JPA 2 and Hibernate offer.
  3. Worrying about very large scale optimization is almost always a premature optimization. I am reading a great book "The Lean Startup" that makes this point very well: avoid making very long term plans, instead favoring short iterations of planning, measuring, then pivot or keep the current plan.
One thing that I believe that both JPA 2 and ActiveRecord do very well is managing transitive relationships. Both can be set to perform cascading deletes, etc. I think that JPA 2 and Hibernate offer a finer control for maintaining associations between objects but for my work I have found ActiveRecord to always be adequate.

I enjoy using both ActiveRecord and JPA 2 enough that I don't really care which platform my customers prefer, and I almost never try to talk my customers into switching away from their platform of choice.

No comments: