Now I know that most of you are familiar with this “as old as the world” problem, so to ease the uprising tension I will not go into the theoretical and architectural kind of stuff. Rather I want to remind to all of us why the (O)bject (R)elational mapping software domain exists nowadays.
In general there are few major obstacles to overcome when designing an efficient N-Tier application. The persistence storage of a modern application is usually a RDBMS. These kinds of systems store information in a highly efficient way and allow fast retrieval, information queries and scalability, and all that because of the normalization theory and Edgar F. Codd. In a typical database you have tables, which consist of columns and rows. The columns represent the schema of the data, whereas the rows contain the real information bound to the particular schema. The tables are bound in so called relations that represent the dependencies amongst the different data sets.
On the other side, majority of the applications are developed using OOD and OOP approaches. In the OOP world you just don’t have strict “schemas” and normalization process, the data is described by using different types, and of course, by using object references (which is different than relations).
So you have two completely different worlds, not just as programming paradigms, but also completely alien in terms of technology approaches. The interrelations between both models are crucial for the application’s stability, performance, and scalability, but suffer because of the following differences:
- Encapsulation – in OOP every class has internal and private implementation that is contained and maintained by the class instance. The external entities do not have access to this “reserved” part of the class instance – it is accessible in a manner to guarantee the class invariant behavior. The public methods should define the “contract” with the outside world. The goals are to have a set of rules that guarantee the valid state of the object instance throughout its lifecycle.
Opposite to that the RDBMS use of public data, which must be amenable to upgrade, inspection and queries. Significantly fewer constraints are applied on the data that represent object characteristics, for example there are no formal “private” and “public” fields that are embedded in the RDBMS technology platforms.
- Data type differences – no pointer/reference data types are allowed in the relational systems. Even more, there are substantial differences between the scalar data types in both OOP and RDBMS models, which cause translation/mapping difficulties.
- Structure and integrity – in OOP it is considered normal to have highly nested structures (objects containing sets of different objects recursively, thus producing quite complicated object graphs). This poses difficulties in translating these structures to relational schemas, where all data is represented in a named set of global, flat relation variables. Also most of the constraints in the relational models are declaratively defined, whereas in the OOP systems this is mostly implemented as verification procedures that rise exceptions and/or implement error handling.
- Manipulating the model – maybe the biggest difference of all is the way we “handle” both models. The relational models have a formalized and well defined set of operators and primitives to query and handle data. The OOP models, on the opposite, use lower level, case and technology specific access, and imperative operations.
- Transactions – a well defined, mission-critical part of the RDBMS systems are the transactions that encapsulate the smallest unit of work performed by RDBMS. Their scope is larger and even not typical for any OO generic system at present. In OO systems at present mostly field-scope or property-scope changes are tracked in transaction mechanisms, which is not even near to what database transactions are capable of. Transaction and consistency are only ensured for changes of primitive typed fields at most in OO systems. In general, no isolation mechanisms are used as well.
So, enough said on what are the real approaches to solving the impedance mismatch problem in object-relational models mapping. There is no complete or universal solution to this, but there are two approaches to solving it: through compensation and through minimization (the second approach is less popular). Minimization generally refers to building object-oriented database systems or having extensions to the programming languages that incorporate the relational models into the OO world (example: transitional memory paradigm). The compensation is typically done trough intermediate frameworks that tend to map the data model entities to the ones used in the OO systems. Such “translation” layers are generally referred to as O/R mappers. Of course there is always the possibility to “cook” something yourself, but personally I prefer using mature and widely used frameworks, whether free or commercial.
Generally they do have a few technical aspects that are used to accomplish their target goals. The most widely used approach is the code generation, where based on some entities model, real code is generated in the project. The code in the form of classes implements the entities from the data model in an OO manner that is easy and simplistic to use in imperative OO languages. Because of its OO nature, the classes encapsulate all the logic that is required to interact correctly with the O/R mapping framework.
So how to solve the O/R impedance mismatch in practice? What frameworks are there on the market? Should you use an Open Source or a commercial vendor product? Maybe just use a code generator with DAL templates instead?
Well, I will be going through all of these questions and lot more in a series of articles that I am starting on the O/R mapping domain.
The journey begins with evaluating general purpose code generation techniques that use templates to generate Data Access Layers. Then I will go through presenting some of the most popular O/R tools on the market. After a short assessment, every O/R tool will be demonstrated in a simple example that includes our RadGridView for Windows Forms control, and possibly RadChart. In the course of doing it, I will present the special features, i.e. the “bells and whistles” of the O/R mappers and our UI components. Then the final verdict on O/R mappers will be issued – the tool that will be used to prepare a real life application based on patterns and best practices…
And understandable styled using our UI components (I will start with Windows Forms, but if there is enough interest, will continue with ASP.NET AJAX, WPF, Silverlight, you name it). I will be experimenting with IoC frameworks on top of the O/R mapping as well.