Despite the best efforts of many, the Object-Oriented vs. Relational Database "impedance mismatch" is still with us. Don't get me wrong; the aforementioned projects and specifications have done sterling work abstracting away tons of tedious, error-prone, boilerplate rubbish so that we can concentrate on our domain model.
But there lies the problem.
Far too often, domain models are so elaborate, so needlessly-baroque and overengineered that actually squeezing them down into two-dimensional database tables takes quite extraordinary levels of hackery. Now that the persistence-layer tools are so good, some developers are failing to stop and think "hang on, just because we can have a seven-level inheritance tree and persist it, doesn't mean we should".
Here's a trivially simple example. The good-old User class. Just about every webapp has one. Let's look at the (imagined) requirements:
- A User should have a login name, real name, email address and (hashed and salted) password
- There should be a special class of User called Admin who has greater power to
mess upconfigure the system
At this point, 8/10 OO developers will get tremendously excited - they've spotted an actual situation where inheritance can be applied!. And we could even stick a Person on the top for people who aren't yet users!:
Person | ^ | User | ^ | Admin
Gosh how exciting!
Except do we really need to model people who don't use the system? Will we ever? And is an Admin really a specialisation of a User? Isn't it actually a role that a user can play? We could persist that far more easily with a simple enumerated type. Or if we're really doing the simplest thing that can possibly work then couldn't we just have a boolean isAdmin flag?
Another example. Consider the classic Parent-Child relationship; let's use Course and Student as our concrete types. Traditional object modeling would have Course holding a collection of Student, with Student holding a reference back to Course. But now stop and think. If all this data is being persisted anyway, how often would we actually use that collection from Java-land? If we really need that information, it's a trivial DAO method away - the parent reference in the child maintains the referential integrity, so why use a bidirectional relationship?
With just a few small optimisations like those suggested above, a lot of the supposed "impedance" drops to zero. So the next time your square object model won't fit through the round RDBMS hole, cut a few corners!