Thursday, October 24, 2013

Understanding Entity Relationship Mapping, Part 1: The basic concepts

It is possible to create a working functionality of a system using tools/technologies that is not fully understood, as long as some minimal knowledge is present: what things are, where to find them, and how to wire them together in other to get them to work. And thank heavens, with the help of search engines, you can easily scour the web for solutions to anomalies that pops up, due to the lack of complete grasp of the tool being used. But without a more in-depth knowledge, or at least a grasp of the basic fundamental concepts, it would become difficult to accomplish more complex or customized tasks, troubleshoot issues and general extend beyond the basic functionality.

This was how I was treating mapping entity relationships in the ORM domain, via Hibernate's implementation of JPA, for a time now. I had the basic knowledge of relational database modelling, how relationships are constructed using primary keys and foreign keys in SQL, how data can be fetched from tables that are related using joins: basic knowledge that has its roots solely in the relational way of looking at databases. So I was able to annotate up entities and set up relationships. Get stuff persisted and maybe updated. But I kept running into minor errors now and then, configuration issues, minor oversights etc.

One of the areas these annoyances kept popping up was in how to describe relationships between entities. After I have had enough of head banging against the wall, I decided to just take a step back to understand, at least, a little bit more, the tool I am using and what I was dealing with here.

Basic Concepts

Before going to the details of actual annotating entities with relationships, some data modelling and Object-Relational model concepts should be known:.

Direction of Relationship

Owning Side and Inverse Side

Cardinality and Ordinarily

Cascading

Single Valued Mapping

Collection Valued Mapping

Direction of Relationship

When two tables/entities are related, you should be able to reach the one from the other. This idea is referred to as the Direction of the relationship.

When you can only reach the second entity from the first, you have a Unidirectional relationship. When you can reach either way, you have a Bidirectional relationship.

For example if you have a Boy Entity and Girl Entity that are in a romantic relationship, you would be able to get to the girl from the boy he is in a relationship with and vice versa. This is bidirectional. But if you have FanBoy and SuperStar entities, you would most likely have a unidirectional relationship where you can reach the SuperStar from the Fan and not the Fan from the SuperStar. For example the relationship I have with Toni Braxton. I know her, I am in love with her music (maybe even more than the music), but she does not know me nor is she in love with my code! :(

Owning Side and Inverse Side.

In your typical Relational way of representing data, you would most likely link one table to another via the use of foreign key (or join tables). So for example if you have a table that holds information about People and another one that holds information about Nationalities, in the People table you would have a column (that would serve as the foreign key) which would hold the identifier (primary key) that points to the Nationality information for a particular person. In such a situation, the table that holds this awareness of the relationship, the foreign key, is called the Owning Side. In our case, the owner would be the Person Table or Person Entity when represented in JPA.

The table that the owning side points to is then referred to as the Inverse side. So using SQL you can easily query the People table for a particular Nationality Id, and use this to retrieve the associated Nationality information. You can also query the Nationality table for an Id, and then check the People table for the Person(s) with that Nationality. In both cases, what indicated the relationship (the foreign key) is found in the Person Table: why it is referred to as the owning side.

Owning side, Inverse Side and how it relates with Direction of Relationship

By default if you have two entities that are related, the entity that has the foreign key (owning side), would be able to access the other entity (inverse side) while the referenced entity won’t have any knowledge of the first entity, thereby making the direction of the relationship a unidirectional one . But at times you would want to be able to navigate to the owning entity from the inverse entity. In this case you use the mappedBy property of the relationship annotation. You see how this is done in the second half of this post.

Cardinality

Cardinality describes the type of the relationship based on the numbers that exist on the sides of the relationship. We have One-To-One, One-To-Many, Many-To-One and Many-To-Many.
1.One-To-One:
A boy and a girl in a monogamous relationship.
2.One-To-Many:
A boy in a polygamous relationship, viewing the relationship from the view point of the Boy Table. i.e. A single boy can points to many girls.
3.Many-To-One:
A boy in a polygamous relationship, viewing the relationship from the view point of the Girl table. Many girls can point to the same boy in the Boy Table.
4.Many-To-Many:
A situation where boys and girls are all in a polygamous relationship; or better put: open relationships

Source and Target

The left side of the cardinality is source while the right side is the target.

Cascading

Cascading is used to indicate whether actions performed on an Entity in a relationship should be propagated to the other entity it is related to. The four operations that can be defined as having cascading properties include: PERSIST, REFRESH, REMOVE, MERGE, and DETACH.

The second half of the post shows how these cascading properties are enforced using annotations. It should be noted that cascading behaviours can be defined on any side, or both sides of entities in a relationship.

Eager Fetch and Lazy Fetch

Eager and Lazy fetch is something you would find only in Object-Relational Model, not in the SQL-Relational world of data representation. Fetch is used to define how data from a related entity is retrieved.

An Eager Fetch states that the related/target Entity should be fetched at the point where the source Entity is fetched. A Lazy Fetch on the other hand, states that the target entity should only be fetched at the point where the field referencing it from the source entity is being accessed.

Ordinality

Ordinality specifies if related parties present in a relationship exist or not. It is basically a value that indicates, at the point of creation of one part of the relationship, if the related entity too should be in existence. To explain, in the Person/Nationality relationship, at the point of creating a Person, the Nationality must be specified. So the Ordinality is 1 (expressed as True, or Yes, or Must, or Required etc.). But in a Boy/Girl relationship, a single boy entity can be created, where the boy does not have a girl entity connected to it. In this case the cardinality is 0 (expressed as False, or No, or Optional etc.).

Single Valued Mapping

This describes a relationship where the right side (target side) of the relationship has single value or single cardinality. Thus Many-To-One and One-To-One are single valued mappings.

Collection Valued Mapping

This describes a relationship where right side (target side) of the relationship has multiple value or cardinality. Thus One-To-Many and Many-To-Many are example of Collection Valued Mapping.

One thing to note is that in both Single Valued Mapping and Collection Valued Mapping, the side that has multiple cardinality is usually made the owning side of the relationship.