CSC/ECE 517 Fall 2009/wiki3 12 Patterns for ORM: Difference between revisions
(39 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
=='''Overview'''== | =='''Overview'''== | ||
[http://en.wikipedia.org/wiki/Object-relational_mapping Object-relational mapping] is not trivial. Apart from being based on Software Engineering principles like coupling, cohesion and polymorphism, the object paradigm focuses on building applications out of objects that have both data and behavior. However, the relational paradigm is based on mathematical principles and focuses primarily on storing data. If only data objects were to be mapped to the relational database the procedure would have been fairly straightforward. With the growing complexities of object models, concepts like aggregation, inheritance, polymorphism, association between classes, and data type (smarted than SQL data types) have to be mapped to relational table structure. The table below highlights the fundamental mismatch between object oriented data model and relational data storage. | [http://en.wikipedia.org/wiki/Object-relational_mapping Object-relational mapping] is not trivial. Apart from being based on [http://en.wikipedia.org/wiki/Software_engineering Software Engineering] principles like [http://en.wikipedia.org/wiki/Coupling_(computer_science) coupling], [http://en.wikipedia.org/wiki/Cohesion_(computer_science) cohesion] and [http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming polymorphism], the object paradigm focuses on building applications out of objects that have both data and behavior. However, the relational paradigm is based on mathematical principles and focuses primarily on storing data. If only data objects were to be mapped to the relational database the procedure would have been fairly straightforward. With the growing complexities of object models, concepts like [http://en.wikipedia.org/wiki/Aggregation_(object-oriented_programming) aggregation], [http://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming) inheritance], [http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming polymorphism], association between classes, and data type (smarted than [http://en.wikipedia.org/wiki/SQL SQL] data types) have to be mapped to relational table structure. The table below highlights the fundamental mismatch between object oriented data model and relational data storage. | ||
{|border="2" cellspacing="0" cellpadding="4" width="50%" align="center" | {|border="2" cellspacing="0" cellpadding="4" width="50%" align="center" | ||
Line 29: | Line 27: | ||
=='''[http://docs.jboss.org/hibernate/core/3.3/reference/en/html/inheritance.html Inheritance Mapping]'''== | =='''[http://docs.jboss.org/hibernate/core/3.3/reference/en/html/inheritance.html Inheritance Mapping]'''== | ||
[http://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming) Inheritance] in [http://en.wikipedia.org/wiki/Object-oriented_design Object Oriented Design] makes it difficult to map between object and relation databases. In this pattern, there is mapper class for each domain class that will save and load data for the domain class [8]. Mapper class allows both abstract and concrete classes to handle their own O/R mapping[8]. | [http://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming) Inheritance] in [http://en.wikipedia.org/wiki/Object-oriented_design Object Oriented Design] makes it difficult to map between object and relation databases. In this pattern, there is mapper class for each domain class that will save and load data for the domain class [8]. Mapper class allows both [http://en.wikipedia.org/wiki/Class_%28computer_science%29#Abstract_classes abstract] and [http://en.wikipedia.org/wiki/Class_%28computer_science%29#Concrete_classes concrete classes] to handle their own O/R mapping[8]. | ||
For example: - To find an employee “John” | |||
[[Image:wiki_3_12.jpg]] [[Image:Wiki_3_12_2.jpg]] | |||
Figure 1: Domain Class Figure 2: Mapper Class | |||
For example: - To find an employee “John”. | |||
Figure 1 represents the Employee Domain class and Figure 2 represents the corresponding Mapper Class. | |||
Application calls find () method on concrete mapper object and instantiate a new Executive object. The find () will pass this executive object and database record to load () of Executive. This in turn will call the load () of Superclass. When all loads return, find returns the filled object. | Application calls find () method on concrete mapper object and instantiate a new Executive object. The find () will pass this executive object and database record to load () of Executive. This in turn will call the load () of Superclass. When all loads return, find returns the filled object. | ||
Mappers loading and saving the domain objects is determined by the inheritance mapping. This inheritance hierarchy is represented in the database as follows:- | Mappers loading and saving the domain objects is determined by the inheritance mapping. This inheritance hierarchy is represented in the database as follows:- | ||
Line 41: | Line 44: | ||
==='''Single Table Inheritance'''=== | ==='''Single Table Inheritance'''=== | ||
Inheritance Hierarchy of all classes is represented as single table. The columns of this table will have fields of all classes in the hierarchy. Advantage of this Inheritance is that there is one table and requires no join while retrieving data. But it could lead to large confusing table and name conflicts. | Inheritance Hierarchy of all classes is represented as single table. The columns of this table will have fields of all classes in the hierarchy. Advantage of this Inheritance is that there is one table and requires no join while retrieving data. But it could lead to large confusing table and name conflicts. | ||
[[Image:wiki_3_12.jpg]] [[Image:Wiki_3_12_3_a.jpg]] | |||
Figure 3: Domain Class Figure 4: Single Table Inheritance | |||
==='''Class Table Inheritance '''=== | ==='''Class Table Inheritance '''=== | ||
One table for each class is constructed. The advantage of this table inheritance is that there is clear relationship between class and table. There is high normalization. But multiple tables requires join and when fields move up and down in hierarchy, it requires changes in the tables. | One table for each class is constructed. The advantage of this table inheritance is that there is clear relationship between class and table. There is high [http://en.wikipedia.org/wiki/Database_normalization normalization]. But multiple tables requires [http://en.wikipedia.org/wiki/Join_%28SQL%29 join] and when fields move up and down in hierarchy, it requires changes in the tables. | ||
[[Image:wiki_3_12.jpg]] [[Image:Wiki_3_12_4_.jpg]] | |||
Figure 5: Domain Class Figure 6: Class Table Inheritance | |||
==='''Concrete Table Inheritance'''=== | ==='''Concrete Table Inheritance'''=== | ||
In this hierarchy there is one table per concrete class. The table are independent, requires no join and there is no unused fields. | In this hierarchy there is one table per concrete class. The table are independent, requires no join and there is no unused fields. | ||
[[Image:wiki_3_12.jpg]] [[Image:Wiki_3_12_5.jpg]] | |||
Figure 6: Domain Class Figure 7: Concrete Table Inheritance | |||
The strengths and weaknesses of each approach are compared below: | The strengths and weaknesses of each approach are compared below: | ||
Line 91: | Line 101: | ||
The [http://en.wikipedia.org/wiki/Foreign_key Foreign key] is used to maintain relationships in relational databases. A row in one table can relate to a row in another table using foreign key. Therefore to implement relationships, a key of one table must include in the other table [4]. | The [http://en.wikipedia.org/wiki/Foreign_key Foreign key] is used to maintain relationships in relational databases. A row in one table can relate to a row in another table using foreign key. Therefore to implement relationships, a key of one table must include in the other table [4]. | ||
==='''One-to-one mapping'''=== | ==='''One-to-one mapping'''=== | ||
If one record in Table A corresponds to exactly one row in Table B, this relationship is called One – to-one relationships [10]. In | If one record in Table A corresponds to exactly one row in Table B, this relationship is called One – to-one relationships [10]. In Figure 6, the address attribute of an employee class forms a one-to-one relation with the address class. In database, this relationship is stored by creating one-to- one mapping between these two objects by storing the id of Address instance in the Employee table instance is written [11]. When the employee is read form database, the address instance is linked to Employee. Here, the mapping is from Employee to Address. | ||
[[Image:Wiki_3_12_6.gif]] | |||
Figure 6: One-to-one mapping | |||
==='''One-to-many mapping'''=== | ==='''One-to-many mapping'''=== | ||
If each record in Table A corresponds to many records in Table B , but each record in Table B links to only one record in Table A, this relationship is called One-to-many relationships [10]. | If each record in Table A corresponds to many records in Table B , but each record in Table B links to only one record in Table A, this relationship is called One-to-many relationships [10]. | ||
In fig, a Order may have zero to many OrderItems. To represent in relational database, the Owner object’s OID can be inserted into OrderItem table [9]. Here, OID is Foreign Key. This is shown in | In fig, a Order may have zero to many OrderItems. To represent in relational database, the Owner object’s OID can be inserted into OrderItem table [9]. Here, OID is Foreign Key. This is shown in Figure 8. | ||
[[Image:Wiki 3 12 6.jpg]] | |||
Figure 8 : One-to-many mapping | |||
==='''Many-to-many mapping'''=== | ==='''Many-to-many mapping'''=== | ||
If each record in Table A may links to many records in Table B and vice-versa [10], it’s called Many-to-Many relationships. In | If each record in Table A may links to many records in Table B and vice-versa [10], it’s called Many-to-Many relationships. In Figure 9, let’s consider that an employee can work more than one department and department can contain more than one employee.<br> | ||
The Many-to-Many relationships is represented in term of association table. A separate table called association table is created that contains the foreign keys of participating tables [9]. | The Many-to-Many relationships is represented in term of association table. A separate table called association table is created that contains the foreign keys of participating tables [9]. | ||
[[Image:Wiki 3 12 7.jpg]] | |||
Figure 9 : Many-to-many mapping | |||
=='''[http://en.wikipedia.org/wiki/Aggregation_(object-oriented_programming) Aggregation] Mapping'''== | =='''[http://en.wikipedia.org/wiki/Aggregation_(object-oriented_programming) Aggregation] Mapping'''== | ||
Line 103: | Line 121: | ||
==='''Single table aggregation'''=== | ==='''Single table aggregation'''=== | ||
In this pattern the a table is created with the attributes of the Aggregating objects. The attributes of the Aggregating object is simple added to this table. | In this pattern the a table is created with the attributes of the Aggregating objects. The attributes of the Aggregating object is simple added to this table. | ||
[[Image:Index.2.png]] | |||
==='''Foreign key aggregation'''=== | ==='''Foreign key aggregation'''=== | ||
To achieve this create a table each for the aggregating and aggregated object. Create a foreign key reference between the two table by inserting a synthetic object identity into the aggregated objects type and reference it in the aggregating objects table. | To achieve this create a table each for the aggregating and aggregated object. Create a foreign key reference between the two table by inserting a synthetic object identity into the aggregated objects type and reference it in the aggregating objects table. | ||
[[Image:Index.4.png]] | |||
Differences between the two approaches has been tabulated below:<br> | |||
{|border="2" cellspacing="0" cellpadding="4" width="100%" align="center" | {|border="2" cellspacing="0" cellpadding="4" width="100%" align="center" | ||
|- | |- | ||
Line 124: | Line 147: | ||
|align="center"|Factoring out aggregated objects allows easy querying these tables with ad-hoc queries. | |align="center"|Factoring out aggregated objects allows easy querying these tables with ad-hoc queries. | ||
|} | |} | ||
=='''Type Conversion'''== | |||
There are situations when the values in the database do not map directly to object data types. Take the Boolean data type for example. Boolean values "true" and "false" may be saved as "T" and "F" respectively in the database. Type conversion should be facilitated without any data loss[2]. The figure below shows type conversion mapping. | |||
[[Image:Tcmapfig.jpg]] | |||
=='''References'''== | =='''References'''== | ||
[1]http://www.objectarchitects.de/ObjectArchitects/orpatterns/<br> | [1] http://www.objectarchitects.de/ObjectArchitects/orpatterns/<br> | ||
[2]http://subs.emis.de/LNI/Proceedings/Proceedings48/GI.Band.48-6.pdf<br> | [2] http://subs.emis.de/LNI/Proceedings/Proceedings48/GI.Band.48-6.pdf<br> | ||
[3]http://www.joeyoder.com/Research/objectmappings/Persista.pdf<br> | [3] http://www.joeyoder.com/Research/objectmappings/Persista.pdf<br> | ||
[4]http://www.ibm.com/developerworks/library/ws-mapping-to-rdb/<br> | [4] http://www.ibm.com/developerworks/library/ws-mapping-to-rdb/<br> | ||
[5]http://www.dparsons.co.uk/mindthegap.pdf<br> | [5] http://www.dparsons.co.uk/mindthegap.pdf<br> | ||
[6]http://proceedings.informingscience.org/InSITE2007/IISITv4p767-779Jusi281.pdf<br> | [6] http://proceedings.informingscience.org/InSITE2007/IISITv4p767-779Jusi281.pdf<br> | ||
[7]http://www.sis.pitt.edu/~gray/INFSCI1025/references/AmblerORMMapping101Article.pdf<br> | [7] http://www.sis.pitt.edu/~gray/INFSCI1025/references/AmblerORMMapping101Article.pdf<br> | ||
[8]http://www.brettdaniel.com/files/2006/inheritancemapping.ppt<br> | [8] http://www.brettdaniel.com/files/2006/inheritancemapping.ppt<br> | ||
[9]http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?MappingObjects2Tables/mapping_object.htm<br> | [9] http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?MappingObjects2Tables/mapping_object.htm<br> | ||
[10]http://databases.about.com/cs/tutorials/a/accessgup7.htm<br> | [10] http://databases.about.com/cs/tutorials/a/accessgup7.htm<br> | ||
[11]http://www.oracle.com/technology/products/ias/toplink/doc/1013/main/_html/relmapun005.htm<br> | [11] http://www.oracle.com/technology/products/ias/toplink/doc/1013/main/_html/relmapun005.htm<br> | ||
[12]http://docs.jboss.org/hibernate/core/3.3/reference/en/html/inheritance.html<br> | [12] http://docs.jboss.org/hibernate/core/3.3/reference/en/html/inheritance.html<br> | ||
[13] http://wiki.eclipse.org/Introduction_to_Mappings_(ELUG)<br> |
Latest revision as of 04:01, 23 November 2009
Overview
Object-relational mapping is not trivial. Apart from being based on Software Engineering principles like coupling, cohesion and polymorphism, the object paradigm focuses on building applications out of objects that have both data and behavior. However, the relational paradigm is based on mathematical principles and focuses primarily on storing data. If only data objects were to be mapped to the relational database the procedure would have been fairly straightforward. With the growing complexities of object models, concepts like aggregation, inheritance, polymorphism, association between classes, and data type (smarted than SQL data types) have to be mapped to relational table structure. The table below highlights the fundamental mismatch between object oriented data model and relational data storage.
Object Oriented Data Model | Relational Database Management System |
Class | Table |
Object | Row |
Entity | Key |
State | Data |
Behavior | Transactions |
Inheritance | Data Relationships |
Inheritance Mapping
Inheritance in Object Oriented Design makes it difficult to map between object and relation databases. In this pattern, there is mapper class for each domain class that will save and load data for the domain class [8]. Mapper class allows both abstract and concrete classes to handle their own O/R mapping[8].
Figure 1: Domain Class Figure 2: Mapper Class
For example: - To find an employee “John”. Figure 1 represents the Employee Domain class and Figure 2 represents the corresponding Mapper Class. Application calls find () method on concrete mapper object and instantiate a new Executive object. The find () will pass this executive object and database record to load () of Executive. This in turn will call the load () of Superclass. When all loads return, find returns the filled object. Mappers loading and saving the domain objects is determined by the inheritance mapping. This inheritance hierarchy is represented in the database as follows:-
- Single Table Inheritance
- Class Table Inheritance
- Concrete Table Inheritance
Choosing a mapping scheme depends on speed requirement, whether database is shared and type of RDBMS.
Single Table Inheritance
Inheritance Hierarchy of all classes is represented as single table. The columns of this table will have fields of all classes in the hierarchy. Advantage of this Inheritance is that there is one table and requires no join while retrieving data. But it could lead to large confusing table and name conflicts.
Figure 3: Domain Class Figure 4: Single Table Inheritance
Class Table Inheritance
One table for each class is constructed. The advantage of this table inheritance is that there is clear relationship between class and table. There is high normalization. But multiple tables requires join and when fields move up and down in hierarchy, it requires changes in the tables.
Figure 5: Domain Class Figure 6: Class Table Inheritance
Concrete Table Inheritance
In this hierarchy there is one table per concrete class. The table are independent, requires no join and there is no unused fields.
Figure 6: Domain Class Figure 7: Concrete Table Inheritance
The strengths and weaknesses of each approach are compared below:
Factors to Consider | One table per hierarchy | One table per concrete class | One table per class |
Ad hoc reporting | Simple | Medium | Medium/Difficult |
Ease of implementation | Simple | Medium | Difficult |
Ease of data access | Simple | Simple | Medium/Simple |
Coupling | Very High | High | Low |
Speed of data access | Fast | Fast | Medium/Fast |
Support for polymorphism | Medium | Low | High |
Association Mapping
The Foreign key is used to maintain relationships in relational databases. A row in one table can relate to a row in another table using foreign key. Therefore to implement relationships, a key of one table must include in the other table [4].
One-to-one mapping
If one record in Table A corresponds to exactly one row in Table B, this relationship is called One – to-one relationships [10]. In Figure 6, the address attribute of an employee class forms a one-to-one relation with the address class. In database, this relationship is stored by creating one-to- one mapping between these two objects by storing the id of Address instance in the Employee table instance is written [11]. When the employee is read form database, the address instance is linked to Employee. Here, the mapping is from Employee to Address.
Figure 6: One-to-one mapping
One-to-many mapping
If each record in Table A corresponds to many records in Table B , but each record in Table B links to only one record in Table A, this relationship is called One-to-many relationships [10]. In fig, a Order may have zero to many OrderItems. To represent in relational database, the Owner object’s OID can be inserted into OrderItem table [9]. Here, OID is Foreign Key. This is shown in Figure 8.
Figure 8 : One-to-many mapping
Many-to-many mapping
If each record in Table A may links to many records in Table B and vice-versa [10], it’s called Many-to-Many relationships. In Figure 9, let’s consider that an employee can work more than one department and department can contain more than one employee.
The Many-to-Many relationships is represented in term of association table. A separate table called association table is created that contains the foreign keys of participating tables [9].
Figure 9 : Many-to-many mapping
Aggregation Mapping
Aggregation is a specialized version of the association relationship. Aggregations may be mapped to relational data model either by integrating all objects' attributes into a single table or using foreign keys.
Single table aggregation
In this pattern the a table is created with the attributes of the Aggregating objects. The attributes of the Aggregating object is simple added to this table.
Foreign key aggregation
To achieve this create a table each for the aggregating and aggregated object. Create a foreign key reference between the two table by inserting a synthetic object identity into the aggregated objects type and reference it in the aggregating objects table.
Differences between the two approaches has been tabulated below:
Single Table Aggregation | Foreign Key Aggregation |
Only one table needs to be accessed to retrieve an aggregating object with all its aggregated objects. On the other hand, the fields for aggregated objects’ attributes are likely to increase the number of pages retrieved with each database access, resulting in a possible waste of I/O bandwidth. | Needs a join operation or at least two database accesses where Single Table Aggregation needs a single database operation. |
If the same object is aggregated in more that on one object, a change in the aggregated object would require a change in a lot of database table. This pattern thus has poor maintainability. | Since the aggregated object has it's own table, the pattern is more maintainable and flexible. |
Aggregated objects are automatically deleted on deletion of the aggregating objects. | Aggregated objects are not automatically deleted on deletion of the aggregating objects. |
Ad-hoc queries are very hard to formulate. | Factoring out aggregated objects allows easy querying these tables with ad-hoc queries. |
Type Conversion
There are situations when the values in the database do not map directly to object data types. Take the Boolean data type for example. Boolean values "true" and "false" may be saved as "T" and "F" respectively in the database. Type conversion should be facilitated without any data loss[2]. The figure below shows type conversion mapping.
References
[1] http://www.objectarchitects.de/ObjectArchitects/orpatterns/
[2] http://subs.emis.de/LNI/Proceedings/Proceedings48/GI.Band.48-6.pdf
[3] http://www.joeyoder.com/Research/objectmappings/Persista.pdf
[4] http://www.ibm.com/developerworks/library/ws-mapping-to-rdb/
[5] http://www.dparsons.co.uk/mindthegap.pdf
[6] http://proceedings.informingscience.org/InSITE2007/IISITv4p767-779Jusi281.pdf
[7] http://www.sis.pitt.edu/~gray/INFSCI1025/references/AmblerORMMapping101Article.pdf
[8] http://www.brettdaniel.com/files/2006/inheritancemapping.ppt
[9] http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?MappingObjects2Tables/mapping_object.htm
[10] http://databases.about.com/cs/tutorials/a/accessgup7.htm
[11] http://www.oracle.com/technology/products/ias/toplink/doc/1013/main/_html/relmapun005.htm
[12] http://docs.jboss.org/hibernate/core/3.3/reference/en/html/inheritance.html
[13] http://wiki.eclipse.org/Introduction_to_Mappings_(ELUG)