Sunday, January 7, 2007

ActiveRecord pattern, so what?

The Active Record pattern has a lot of publicity recently thanks to the Ruby On Rails and Grails wave. A definition could be: an object that encapsulates both data and behavior (ie a database row and it's data access logic).

A bit of history
I was asked recently my thoughts about this pattern. First of all, if someone still remembers EJB 1.0 and 2.x Entity Beans, this was a perfect example of the Active Record Pattern... and a successful failure. Some of the reasons for this failure was the tight link between the data and it's access logic: Serialization issue, data tight to a persistent technology etc etc.

Statically typed languages
To me the ActiveRecord pattern is not well suited for statically typed languages like Java, hence the raise of another pattern : DAO (aka DAL in the .net world). It prevents the hard link between the persistence technology and the actual data representation.

Dynamic languages
Dynamic languages (and to a certain extend AOP) have the nice ability to decorate an object with additional features on the fly, without linking it "the hard way": you can then easily reuse your domain classes out of the persistence context.
Grails uses such a behavior to add CRUD operations transparently to your domain model (with quite complex Querying capabilities).
One still face a problem, what if the application developer needs to add a more complex persistence operation (esp a query), he will end up "hard-coding" the function to the domain object and we're back to the issue faced by statically typed languages... unless you create a DAO object. But then, your persistence operations will be split between your implicit domain model methods and your DAO: another code smell.

Dynamic DAO
As you can see, I'm not keen on the ActiveRecord pattern (out of simple applications), but I really love the simplicity of GORM (the Grails way). The solution is a dynamic DAO. JBoss Seam already generates very simple yet powerful DAOs benefiting from Java Generics. If you combine that with a dynamic language, you can have the best of both worlds.

class UserProcess {
@In UserDao userDao;

void create(String firstname, String lastname) {
if (userDao.countByFirstnameAndLastname(firstname, lastname) == 0) {
def user = new User( "Emmanuel", "Bernard" )
userDao.save user
}
else {
throw new UserAlreadyExistException()
}
}
}


Note that countByFirstnameAndLastname and save can be dynamic methods à la GORM.

Conclusion
I'm not a big fan of the ActiveRecord. For static languages, I would use the DAO approach. For dynamic languages, I did not make up my mind but a DAO on steroids seems very promising.

5 comments:

Anonymous said...

Interesting post.

By the way, you mean à la instead of "ala".

Unknown said...

Fixed thanks. Yes I meant à la française :-)

Tetsuo said...

If using Spring, one could use a FactoryBean that takes a incomplete (abstract) implementation of a DAO and 'fill in the blanks'.

For example, it could have a abstract 'countByFirstnameAndLastname()' method (and no source in the project actually implement this), and have this factoryBean to return a CGlib-generated subclass, that implements the method based on naming conventions. The non-abstract methods would remain intact.

This would enable a kind of 'dynamic DAO' in the static-typed Java! The declaration would still be mandatory (to satisfy the compiler), but no further code would be required.

What do you think about this?

Unknown said...

Your solution would work with any container esp EJB3, not especially Spring (you actually don't need AOP, a simple interceptor would do the job). But you still have to change your class and redeploy your application at best run an ant script, so you don't benefit the dynamic language speed and DRY principle.

BTW JBoss Seam does hot redeployment of components (no EAR redeploy), which solves the redeploy issue even if you don't use Dynamic languages.

Anonymous said...

Thanks for the nice post!