Monday, February 1, 2010

ActiveRecord in Java == ActiveJDBC

As a Java developer, I spent a a couple of years working in a mixed environment where Java and Ruby intermixed. Working side by side with Ruby developers made me aware of things outside the Java world. To some extend, this was my own fault for ignoring the Ruby world. I clearly remember beng at the SD West conference in 2005 when the Ruby frenzy began. I looked at what RoR can do and was unimpressed by it mostly because the presentations at the conference focused on generating an application from scratch using scaffolding. Having to implement web app generators for Hibernate/Tiles/Struts-Layout two years prior, this looked boring and I put my interest to Ruby on the back burner. I was wrong. A couple of years later, working in a mixed environment (Java/Ruby) I learned a whole a lot more about Ruby and Rails, and was pleasantly surprised by the level of innovation. Over the years I have developed somewhat a disgust for big frameworks and "architectures" using them. The biggest offender IMHO is Spring. I really, really, REALLY do not understand what value it provides. The Spring context files multiply like rabbits, making it extremely difficult to debug the application. As you can imagine, in a mixed environment, there were many heated discussions on the merits of different languages, and I tended to protect Java, stating that the Java environment was poisoned by large useless frameworks as well as a large number of corporate developer-drones, and really there is nothing wrong with the language. The argument that the Ruby folks had was that Ruby is more elegant, dynamic and powerful and therefore attracts a more sophisticated crowd. My arguments that there are plenty examples of outstanding software created in whatever language (including Java) were just brushed aside.  On the flip side, when Ruby becomes as successful and as prominent as Java, it too will be flooded by corporate bonehead developers. I think that some of the Ruby folks behave as Ruby were a cult, not another tool at developers' disposal. So, to make the story short, the desire to prove that it is totally possible to create a lightweight persistence layer in Java similar to ActiveRecord, and make it even simpler to use in some regard, as well as desire to roll up my sleeves and just do some coding (I have done too much architecture and management over the past few years), drove me to create another ORM framework in Java, named ActiveJDBC.
The idea is to model the behavior and feel similar that of ActiveRecord, but make it for the Java developer. It is amazing how little Java developers know of Ruby. RoR has some great features, and despite the fact that there is no method_missing in Java, many ideas are possible to borrow and implement in Java.
The ActiveJDBC is already used on one commercial project, and according to developers who are used to Hibernate, they "do not even notice it, it just works".
My design goals were:
  • Should infer all metadata from DB (like ActiveRecord)
  • Should be very easy to work with
  • Should reduce amount of code to a minimum
  • No configuration, just conventions
  • Some conventions are overridable in code by simply calling methods (this will be aided by IDEs)
  • No need to learn another language
  • No need to learn another QL - SQL is sufficient
  • Code must be lightweight and intuitive, should read like English
  • No sessions, no "attaching, re-attaching" 
  • No persistence managers. 
  • No classes outside your own models.
  • Models are lightweight, no transient fields
  • No proxying. What you write is what you get (WYWIWYG :))
  • Should have the least possible resistance to startup a project
  • No useless getters and setters (they just pollute code). You can still write them if you like.
  • No DAOs and DTOs  - this mostly junk code anyway
Well, enough suspense, I can say that I started development on my free time around September, and at the end of October I had something I could use in a real system.
Let's look at code examples.
Here is an example of a model:

public class Person extends Model {}

Despite the fact that there is no code in it, it is fully functional and will map to a table called PEOPLE automatically. Here is how to use it:

List<Person> people = Person.find("name = 'John'");
Person aJohn =  people.get(0);
String johnsLastName = aJohn.get("last_name");

As you can see, the amount of code is reduced to a level when it is actually readable.
Finder methods can also be parametrized like this:

List<Person> teenagers = Person.find("age > ? and age < ?", 10, 20);

ActiveJDBC supports many features and is great for building web applications as well. It has a nice validation mechanism similar that of ActiveRecord, automatic support of many to one and many to many relationships, batch deletes and updates (conditional too), etc. Too many to list. I hope this wets your appetite. Any feedback and suggestions are welcome.

cheers!

15 comments:

Nick Zalabak said...

I wonder where the initial inspiration came from? :)
Well done, but where is the link to your source code?

Igor Polevoy said...
This comment has been removed by the author.
Igor Polevoy said...

The source code will be published under Apache SF 2.0 license. I will put more blogs in the future to see if this will attract some interest.

Min Cha said...

Hi. I also have a plan to develop a similar project. The major goal of the project is providing ActiveRecord pattern on Java. Maybe JPA and Hibernate are used for achieving the goal. I think that I can collaborate with you. If you are interested in this suggestion, please send email to me.

Igor Polevoy said...

Min Cha, we can certainly collaborate, but I really do not see how JPA and Hibernate can help. GORM for instance wen in a different direction by wrapping dynamic functionality on top of Hibernate, but this is impossible in Java since it is a static language. I started this implementation in September 2009 and it is working currently in production at an insurance company. There are still pieces of functionality I want to complete, but lately development is slowing down due to lack of time. What you see in this blog post is not a POC, but really an example of a working framework. I should start posting many more cases of usage for people to see.

Min Cha said...

Hello.

I have just implemented my core idea as conceptual version at http://code.google.com/p/hiverecord. Hibernate and JPA are used.

As you mentioned, Java is a static language so it has limitation. My intention is providing ActiveRecord feature as sophisticated as possible in pure Java.

But I am interested in your approach. I hope to see your next post and more examples.

Cheers.

Igor Polevoy said...

I looked at your code, and it does look interesting. However, my goals were not to use Hibernate at all (or any other framework), but rather write all from scratch. I will post some more info on how it works.

Teja said...

Igor, looks awesome man... Eagerly waiting for the source code.. I can't make it for the presentation at Thought Works (am in FL now).... proud that I worked with you guys...

Igor Polevoy said...

Teja, thanks for your comment, the source code is published here:
http://code.google.com/p/activejdbc/

Thanks!

igor

Anonymous said...

Enjoyed reading/following your page.Please keep it coming. Cheers!

Igor Polevoy said...

This was one of the older postings. See newer posting on this blog: http://igorpolevoy.blogspot.com/ , as well as here: http://java.productiveedge.com/.
The project home is here:
http://code.google.com/p/activejdbc

enjoy
igor

Mohamed Elbeltagy said...

First of all, I would like to congratulate you on your project, ActiveJDBC as it has accomplished the goals of simplicity you promised.

But, please don't turn it into another ORM monster by adding more and more features to its core.

If I may suggest, you can add more features as separate libraries.
But keep the core as simple as possible.

Wishing you the best of luck on your project. I'll use it for sure in our upcoming project.

Igor Polevoy said...

Mohamed, thanks for your comment, I do not have any intentions to load this with more and more stuff. My intentions were to create a simple, intuitive and fast ORM that covers some 80% of the usage patterns. Currently ActiveJDBC is only 120k and runs about 40% faster than Hibernate. I feel pretty comfortable at this level. I will be adding small features from time to time very carefully, and of course fix defects as they are discovered.

Lukas Eder said...

+1 for correctly using "corporate bonehead developers" in a sentence! :-) and
+1 for the nice framework.

I am looking forward to getting some inspiration about active record functionality for my own project:
http://jooq.sourceforge.net

I'm sure that I will find some interesting ideas, even if our tools are essentially orthogonal in what they have been made for.

Igor Polevoy said...

Lukas, thanks for comments, feel free to borrow anything AJ has to offer. Let me know if you have any questions.