My gripes were twofold:
- one, that adding in an intermediate layer like this needs to be documented absolutely fully, otherwise you're going to hit a corner case you're unable to solve. Making the mapping library open source mitigates this somewhat as you can dig around inside to see what the problem is, but then you start to lose the transparency of the system, which is the main benefit of having it in the first place. Is it worth having wrappers that you keep needing to unwrap? Debatable.
- two, that often what you need from the database doesn't map directly to your objects very well, which is unfortunately what the mapper usually gives you. This is (rather pretentiously) referred to as the object-relational impedance mismatch. Usually it refers to the trouble trying to represent your OO hierarchy in database form, or vice versa. But I think there's another interesting distinction, and that is in how the data is used.
On an abstract level (think 'whole procedure' rather than 'line of code'), when an application is modifying data, it's typically modifying one object at a time. Sometimes it writes out a few sub-objects, but predominantly I'd say that you write to one object. Examples: when your library management system notes a book has been borrowed, it creates a row in a Loan database. Or when you update your game characters, you typically adjust position and AI state of each character in turn with minimal or no writing done to other characters. Generally speaking, you write one thing. When you insert a MIDI note into your music package, you're typically altering a single track.
However, staying on that same level, when you read data you're often reading several objects at once. When the library management system checks for late loans it typically cross-references them with the Users, to generate reminders. When you perform collision detection, you often want a data structure that can instantly give you the subset of characters that lie within a certain distance, to be tested against. When you're playing back your MIDI song, it's pulling events from several tracks and parameters from the instruments and effects simultaneously to generate the output that you hear.
SQL itself recognises this - compare the complexity of typical SELECT statements, both in practice and in what the statement allows for, with the relative brevity of the typical UPDATE or DELETE statement. Whether you consider that deliberate or an artefact of the implementation is another matter, of course.
But this leads me to thinking: is object-orientation fundamentally a data writing paradigm and relational data (and by extension, structural data such as C's structs) a data reading paradigm? Is object-oriented querying inherently cripped by design? And is a relational database generally much poorer for editing data than for storing it?