ServicesResourcesConferencesOur TeamWeblogsAboutContact
   
Map This!

I'm guilty. I don't believe in O/R Mappers as general purpose solution for all applications. I think that they have some place in this world but wouldn't necessarily see them as the centerpiece of data access in most software architectures.

For me using an O/R Mapper feels like deliberately trying to unify the worst of the object oriented and the worst of the relational world. It seems to me that everyone who wants to convince me to love their O/R Mapper forgot about the real power of SELECT. They believe that SELECT's main purpose in life is to, well, select some data which would nicely map to the object oriented world.

In reality however, SELECT is an easy-to-use means for transformations. In fact, it is so easy-to-use that most people don't even think about transformation when using SELECT. But nevertheless, every SELECT essentially generates new types (let's call them "result sets" or "dynamic views") on the fly [1]. Using on O/R Mapper limits this ability. To correctly support SELECT in the object-oriented world, a statement like "SELECT C.CID, C.NAME, COUNT(O.ORDERID) AS NUMORDERS FROM CUSTOMERS C LEFT JOIN ORDERS O ON C.CID = O.CID GROUP BY C.CID, C.NAME" would have to dynamically create a type similar to this one:

public class DynamicResult_794F3A76_4E8E_4d19_973C_91C88BD95520
{
   public int CID;
   public String Name;
   public int NumOrders;
}

But even if this would be the case, it's usually still too hard to deal with dynamically created types in OO languages. That's why runtime-typed constructs like Datasets, Recordsets, or Resultsets exist.

I also tend to have some issues with the fact that constrained transactional updates like "UPDATE INVENTORY SET AMOUNT=AMOUNT-4 WHERE ARTICLEID=42 AND AMOUNT >= 4 " are not easily portable to OO systems. It's simply not possible to create an object-oriented equivalent of the transactional constraint "AMOUNT >= 4" as long as you don't use pessimistic locking in your O/R Mapper. And we don't really want to even think about this, right?

[1] In fact, you are executing a transformation/new-type-creation if you just run "SELECT * FROM CUSTOMERS". The return type of this instruction is not your "CUSTOMERS"-type/table, but instead another type which might be structurally equivalent. SQL hardly ever cares about anything but structural equivalence, so that the type's names usually don't matter too much. Another fact which doesn't really increase the ease of interoperability with the object oriented world.

posted on Tuesday, January 06, 2004 7:45 AM

Powered by Community Server, by Telligent Systems