JPA / Hibernate. How is a subclass type determined when a superclass is requested?

I just noticed this bevahior at Hibernate and found this a bit awesome (in a welcoming way). I have one type of entity, called SyncItem , which serves as a superclass for a number of other objects. The inheritance strategy is set to InheritanceType.JOINED , so there is a separate table for all fields in the superclass, and subclass tables include only fields for everything added to the subclass, plus a link back to the superclass table.

So, for example, my SyncItem table looks like this:

 mysql> describe syncItems; +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | hidden | bit(1) | NO | | NULL | | | title | varchar(255) | NO | | NULL | | | createDate | datetime | NO | | NULL | | | modifyDate | datetime | YES | | NULL | | | deleteDate | datetime | YES | | NULL | | +------------+--------------+------+-----+---------+----------------+ 

And if I have a subclass of Property , it can get a table like:

 mysql> describe properties; +--------------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------------+--------------+------+-----+---------+-------+ | syncId | bigint(20) | NO | PRI | NULL | | | propertyCode | varchar(255) | YES | | NULL | | +--------------+--------------+------+-----+---------+-------+ 

Now I have about a dozen different subclasses, and it surprised me that I have a query like:

 @NamedQuery( name="SyncItem.findByTitle", query="SELECT s FROM SyncItem s WHERE s.title = :title") 

When I wrote this, I expected that, as I select from SyncItem , I would only return the information contained in the superclass table (i.e. to get an instance of SyncItem , not a Property example). However, when I ran it, I found that the query actually returns the correct instance of the subclass. This is good because it simplifies the implementation of a number of things.

However, I wonder how JPA / Hibernate can return a subclass? He does not know that this title will be displayed on Property , and not on something else, and, as far as I can tell, it does not have a direct mapping from syncItems to properties (instead, it should display the opposite from properties to syncItems ). Is there a connection to each individual subclass table when this query is executed? If so, does that not make the request very expensive?

So yes, it’s just interesting what’s going on behind the scenes.

+4
source share
2 answers

Yes, it does a join for each subtable. It's expensive, but you can use either of the other two strategies to inherit inheritance.

Here you can find the link where it is indicated:

unified strategy is often the slowest of inheritance models. Retrieving any subclass requires one or more database connections, and storing subclasses requires multiple INSERT or UPDATE statements

Each of the three available strategies has its advantages and disadvantages (if you prefer to save space instead of time or a compromise between them). The choice also depends on what operations you will perform on these tables more often. In the link that I inserted, you will find a pretty good and simple explanation for each of them.

+4
source

I believe that it unites all subclasses. This is probably more expensive than not joining, but not so much as indexes are indexed and only one table will contain the required key. Using inheritance will inevitably have some overhead.

You can see the output of the SQL log to see for yourself.

+1
source

All Articles