Nathan's Tech Blog

Monday, August 22, 2005

ActiveRecord and Hibernate code comparison

First, let me say that I'm not anti-Ruby or anti-Rails. Ruby looks really cool, and I hope to dig in and build a Rails web app "real soon now."

However, I feel that various Java/RoR comparisons are often quite one-sided. For an example, check out this comparison of Hibernate and ActiveRecord (RoR's O/R mapping engine) on lesscode.org.

So, what's wrong with this example, which shows how 30 lines of Java and XML Hibernate code gets condensed to three lines Ruby/Rails/ActiveRecord code?

First, this example uses all of the ActiveRecord defaults and none of the Hibernate defaults. The Hibernate XML mapping, by using defaults, could easily be simplified to something like this:

<hibernate-mapping>
<class name="models.Order">
<id name="id" unsaved-value="null">
  <generator class="native"/>
</id>
<set name="items" cascade="all">
  <key column="order_id"/>
  <one-to-many class="models.Item"/>
</set>
<property name="name" length="50"/>
</class>
</hibernate-mapping>

Second, this example doesn't use the "state of the art" Java persistence. That would be Hibernate in JDK 1.5 with EJB 3.0 annotations. With that, the code might look like this:


@Entity
public class Order {
  private Set items;
  private String name;
  private Long id;

  @Id(generate=GeneratorType.AUTO)
  @NotNull
  public Long getId() { return id;}
  public void setId(Long id) { this.id = id;}

  @OneToMany
  @JoinColumn(name="order_id")
  public Set getItems() { return items;}
  public void setItems(Set items) { this.items = items; }

  @Length(max=50)
  public String getName() { return name; }
  public void setName(String name) { this.name = name; }
}

(Note: I haven't tried to compile this, but it's pretty close.)

Third, the ActiveRecord example doesn't show the whole story. It won't work (and really is quite worthless) without a corresponding table in a database. So, the ActiveRecord example should include something like this:


CREATE TABLE ORDERS
(ID INT NOT NULL AUTO_INCREMENT,
NAME VARCHAR(50),
PRIMARY KEY (ID));

Note that the Java (with optional XML) examples above can be used by Hibernate to generate the SQL from the O/R mapping definition.

So, we're left with this...
Hibernate w/XML: 11 lines of Java code, 12 lines of XML
Hibernate w/Annotations: 11 lines of Java code, 6 lines of annotations
ActiveRecord: 3 lines of Ruby code, 4 lines of SQL

So, Ruby on Rails still wins (with less than 1/2 of the code). But not by as much. And Java's main problem with code length now boils down to those messy getters and setters.

0 Comments:

Post a Comment

<< Home