In my earlier post, I talked about the various strategies to map Java class hierarchy onto a database using Hibernate. However, I left out the implications for polymorphic queries and associations. In this post, let me deal with the polymorphic queries. In Hibernate literature you will see that one of the strategies is mentioned as using “implicit polymorphism”.
It always bothered me that the word “implicit” was explicitly mentioned for one of the strategies (table per concrete class with implicit polymorphism) and the word “explicit” was not mentioned for the others (in other words – it was implicit!) So what is “implicit” about the implicit polymorphism?
Before that, let’s look at what a polymorphic query is. In my previous post, I took an example of a Java class hierarchy. In this, class
Vehicle was the class that was extended by some other classes forming a hierarchy. Assume that there are records in the database (don’t worry about the mapping strategy at this time). If we form a query such as “
from Vehicle“, we will get a list of all
Vehicles – instances of
Train are in this list. This behavior is there for all mapping strategies. So what’s the catch – meaning what is this explicit/implicit difference? Let’s work backwards, go from the database to the mapping to the Java classes.
Let’s look at the table structures one more time.
Looking at picture 1, you can figure out that because there is a foreign key in Automobile, Plane and Train tables referring to the Vehicle table’s primary key. There is a relationship between these entities. The database table structure is made aware and you can deduce a hierarchy just by looking at the structure. The Hibernate mapping file also will give you this information because it will have a
<class> mapping which includes the
<joined-subclass> elements in it. Looking at the mapping file, you can again see that there is a hierarchy that we are dealing with. In other words things are explicit and laid out in front of you. This is a table per class (aka table per subclass in Hibernate lingo) mapping style.
Now look at this second picture.
You can see a discriminator column. It is not an attribute in the Java classes and it gives a hint that values in this column will decide which specific class a record belongs to. Coming to the Hibernate mapping file, you can see the use of
<subclass> elements inside the
<class> mapping element. Again it is laid out in front of you that a hierarchy is mapped. This is the table per class hierarchy mapping strategy.
In both these cases, Hibernate is explicitly made aware of the hierarchy. It also reflects in the database schema. Now look at the picture below. Can you tell if the tables are related?
The only chance is if you seek meaning of the names of the tables/columns and make a guess. What if the names were jumbled? The database schema has no awareness of Java class relations (of hierarchy). Any clues in the Hibernate mapping file? If you had used the
in your mapping, then that’s a clue that we are talking hierarchy. In other words, you have made Hibernate aware that there is a hierarchy that you are mapping and that you are not going to repeat the base class attributes for each subclass.
Now coming to the fourth mapping strategy – actually a subtype of the (third) table per concrete class mapping. If you are having the schema as picture #3 above and you have mapped each of the classes separately in their
<class> elements, you have not expressed that there is a relation between these classes. A stranger looking at the schema and the mapping files can certainly deduce that these are unrelated classes mapped in unrelated tables. However, Hibernate knows that there is a relation between these classes even though you have denied it this knowledge through explicit means. It scans the Java classes and figures out that there is indeed a relation. In other words, it implicitly figures out things. So when you fire a “
from Vehicle” query, it goes and fires as many select statements as there are classes under
Vehicle. Agreed that this may be inefficient, but that’s a different issue.
I hope this clarifies for you what the implicit means in the mapping strategy. Do let me know if this improved your understanding.