Back in 1998 I started working as a Delphi developer for a company that had it’s own in-house tool for handling the mapping between object and database, a tool that was already cross platform, having been ported from the original system to Delphi.
Pay attention to that date - it’s well before object oriented development was popular, and long before most modern ORMs were more than a gleam in their developer’s eye. In fact, the very term ORM was unknown to us - we referred to it as the data access layer, but any modern developer would immediately classify it as an ORM.
One of the key features of this ORM is something that would be considered heretical by most modern developers - it wasn’t based on POCO/POJO semantics. Not only was there a distinct base class used for all persisted objects, but the properties exposed by the objects weren’t simple values but full objects in their own right.
Let’s consider what a simple Person class might have looked like - a C# declaration (if there had ever been a version ported to .NET) might have looked like this:
While this looks slightly complex, it wasn’t a burden as we had a visual designer for creating our classes and all the required code declarations were generated on demand.
Since each property was a full object, we had access to a lot more information about each one than you have in a
POCO/POJO environment. We could, for example, easily tell if a property had been modified since loading, or what the
original value was. A C# declaration for
Property<T> might look like this:
As you’ll probably appreciate, these capabilities were very useful both server side and client side - and yes, we had the same object model available on both the server and client.
Associations between objects were also implemented with dedicated objects, allowing any developer to easily access related objects, or even detect whether an association had been loaded or note.
If we had a customer object in an ordering system, the declaration might look like this:
Associations to collections of objects were especially powerful, with constructs allowing the number of associated objects to be accessed without loading the collection prematurely.
One of the classic issues with using an ORM is the Select N+1 problem, where performance of a loop is poor because of a database hit every iteration. Avoiding this problem was relatively easy, as we could use a block load to load a specific association for a collection of objects.
If we wanted to load the
HasPlacedOrders association for a list of Customers, we’d have written code like this:
I spent several years working with this ORM, ending up as one of the maintainers of it’s Delphi codebase and watching as it was ported to a third platform, Java. Working with POCO/POJO based ORMs (including Nhibernate) in the years since has been a productive experience, but it’s never been quite as powerful or easy to use as the original I learnt way back when.