More XML than code?

Posted by    |      

In this article on JavaLobby, Daniel Spiewak, the creator of something called ActiveObjects takes some pot shots at Hibernate, and compares Hibernate negatively with Ruby's ActiveRecord and ActiveObjects. Now, I'm always interested to read informed criticism, but in this case, Daniel seems to be comparing these brand new frameworks against Hibernate2, released in 2003, before I joined JBoss. He says:

Think about it, when's the last time you tried to configure a Hibernate project from scratch? You have to write more XML than code!

Er. Last time I or most other users of Hibernate3 tried to configure a Hibernate project, the only XML they needed to write was the persistence.xml file, which contains basic database connection settings. If Daniel has discovered some magical means to automatically intuit the database that the user wants to connect to, without the user needing to type in the JDBC URL, I would just love to hear about it ;-)

Daniel goes on to claim:

We have a simple table which has a one-to-many relationship with another table. Each table has a few values and a primary key (id). Now in Hibernate, we would map to this schema using a pair of Java beans and mountains of mapping XML.

Of course, Hibernate Annotations has been around since early 2005 and there is no longer any good reason for people to define mappings in XML.

So, to solve this non-problem of mountains of XML, Daniel was inspired by Ruby's ActiveRecord. The code example he gives is the following:

class Person < ActiveRecord::Base  
   belongs_to :company  
end
class Company < ActiveRecord::Base  
   has_many :people  
end

At this point, most developers are thinking um, ok, so how the hell am I supposed to know what attributes a Company has by looking at my code? And how can my IDE auto-complete them? Of course, the Rails folks have a quick answer to this question Oh, just fire up your database client and look in the database!. Then, assuming that you know ActiveRecord's automagic capitalization and pluralization rules /perfectly/, you will be able to guess the names of the attributes of your own Company class, and type them in manually.

Somehow, excitement about the Ruby language has warped their perceptions to such an extent that these people actually believe that this is a /good thing/!

Fortunately, Daniel's product does not implement this absurd approach. In ActiveObjects, you /do/ have to list the attributes of Company. In ActiveObjects, our Company class looks like this:

public interface Company extends Entity {

   public String getName();  
   public void setName(String name);  
       
   public String getTickerSymbol();  
   public void setTickerSymbol(String tickerSymbol);  
       
   @OneToMany  
   public Person[] getPeople();

}

Oh, except that it's not a class at all :-/ So if I have methods that perform business logic, or validate internal constraints, I have nowhere to write the code! Now, this problem could in theory be solved by using an abstract class instead of an interface, and using a bytecode library like CGLIB to generate the implementation class. Unfortunately Daniel's product does not currently support that, since his implementation uses JDK dynamic proxies.

So, exactly what problem has ActiveObjects solved? Is writing the implementation of getName() and setName() /really/ reducing your project's productivity? C'mon, my IDE can do it with a single keyboard shortcut! The equivalent code in Hibernate or any other JPA implementation looks like this:

@Entity
public class Company extends Entity {  
   private String name;  
   private String tickerSymbol;
   @OneToMany private Person[] people;

   public void getName() { return name; }  
   public void setName(String name) { this.name = name; }

   public void getTickerSymbol() { return tickerSymbol; }      
   public void setTickerSymbol(String tickerSymbol) { this.tickerSymbol = tickerSymbol; }

   public Person[] getPeople() { return people; }
   public void setPeople(Person[] people) { this.people = people; }

}

(Where Entity is some class I wrote that defines the id attribute.)

Note that I did not need to write any XML, let alone mountains of the stuff.

I really don't think this code is significantly more complex or difficult to type than the ActiveObjects version (in fact, in a modern IDE, it probably requires /fewer/ keystrokes to produce). Even better, I don't need to use any funny API to instantiate this class. I can just use new and be done with it.

And I think the code is a lot clearer and more explicit than the ActiveRecord version. Object orientation was very much intended for modeling business domain objects like Company and Person. It seems more than strange that Rails would essentially delegate the business domain model to the database.

Update:

Emmanuel just noticed that on this page it is claimed that:

AO also has the potential to have significantly superior performance to more traditional ORMs such as Hibernate because it is lazy-loaded with a multi-tiered caching system.

Curious. Hibernate has had lazy loading and a multi-layered caching system since 1.x versions. I wonder if Daniel has ever actually /used/ Hibernate?


Back to top