Sunday, August 20, 2006

On the use of Hibernate

Someone asked me today whether uPortal uses Hibernate. Per my preferred approach of being as open as possible about as much as possible, this is mostly what I said:

No version of uPortal 2.x uses Hibernate for anything and therefore no uPortal 2.x release of any flavor includes it.

The quickstart (and the slowstart) versions of uPortal 2.x for as long as I can remember ship with and use by default HSQLDB, an in-memory database, for demonstration purposes.

A pain point in uPortal 2.x is its *not* using an ORM framework like Hibernate and therefore its baking-in of hard coded SQL statements. It does some heroics to provide a general XML language for describing the desired initial schema and data content of the database and to provision that database. There are advanced features for upgrading the database automatically.

Frankly, this is the kind of academic brilliance that is both uPortal's strength and its curse. I wouldn't trust these advanced upgrade facilities without paying a whole lot of attention to the log of what they did, and with that amount of attention I can just perform schema updates manually.

A fine alternative to automating the schema and database update process is to carefully craft upgrade SQL scripts for each supported platform. The schemas don't change enough for this to be prohibitive, and when they do change, it's worth being very sure and careful about that change. You're typically supporting uPortal on a few (one?) very specific platforms through a few very specific upgrades.

In any case, in uPortal the DBLoader functionality handles cross-database initial provisioning, and adding another supported database for initial provisioning is not hard.


At runtime, uPortal also does some heroics to flavor-test the underlying database and to choose SQL syntax -- join syntax and the like -- and in some places outright chooses among multiple available SQL statements to work in whatever RDBMs we're running against.

This pain point is real -- if you point it to another database, it probably won't work until you go adjust the SQL -- and yet it is one that I think is greatly overstated. The introduction of DAOs and a wiring framework to choose DAOs that fit with the chosen database is an excellent architectural step forward and would allow the framework itself to support wiring in different DAO impls where that non-lowest-common-denominator-SQL really is buying something.

However, doing this for uPortal 2 would not be hard and would be valuable. It might not look very pretty especially first off. First off we do something awful like externalize the SQL and let people swap properties files. This fixes the problem at the expense of locality -- I'm convinced by the points in Rod Johnson's book on this topic. So the next step would be to re-embed the SQL in DAO implementations that are generic or specific and multiple as necessary. And adopt Spring as the sane wiring mechanism to choose among these.

We're still not talking an insurmountable work, but there we have a solution wherein you can rapidly follow a recipe to choose the impls specific to your database yet replace any given impl. If you've invested in an Oracle database and want to get actual value out of that massive investment by composing stored procedures and views and the like, this is how you do that.



uPortal 3 adopts Hibernate, behind Spring-wired DAOs so that you could still replace any given hibernate-implemented DAO with an RDBMS-specific DAO implementing institution-local data access behaviors, such as accessing that expensive database's stored procedures. It still uses Dbloader-improved functionality for seeding the database. Hibernate solves the cross-platform data access problem.

uPortal 3 also introduces a comprehensive caching layer wherein almost all DAOs are fronted by "Registries" that implement caching, such that many queries will not hit the database. Ideally all caching occurs at this layer and fronting code always consults the Registry, solving another pain point of updated data not being reflected in some places in uPortal 2 without a restart. (Under the uP3 approach, just flush the registry using a convenient administrative portlet).

No comments: