|

Hibernate Tips: How to select a specific subclass from an inheritance hierarchy


Take your skills to the next level!

The Persistence Hub is the place to be for every Java developer. It gives you access to all my premium video courses, monthly Java Persistence News, monthly coding problems, and regular expert sessions.


Hibernate Tips is a series of posts in which I describe a quick and easy solution for common Hibernate questions. If you have a question for a future Hibernate Tip, please leave a comment below.

Question:

I have a many-to-many association to the superclass of an inheritance hierarchy. How can I select only a certain subclass from that hierarchy?

Solution:

You can use a TYPE expression in your JPQL query to limit your query result to one or more subclasses. Let’s take a look at an example.

Authors can write different kinds of Publications, like a Book or a BlogPost. You can model that with an inheritance hierarchy and a many-to-many association between the Author and the Publication entity. In this example, I map the inheritance hierarchy with the InheritanceType.SINGLE_TABLE strategy. So, all entities of the hierarchy are mapped to the same table.

Let’s select all Books that were written by a specific Author. I, therefore, join the Author and Book entities in the FROM clause, check that the Author‘s firstName is equal to ‘Thorben’ and use a TYPE expression to select only Book entities.

Query q = em.createQuery("SELECT b FROM Author a JOIN a.publications b WHERE a.firstName = 'Thorben' AND TYPE(b) = Book");
Book b = (Book) q.getSingleResult();

log.info(b);

As you can see in the log output, Hibernate uses the discriminator column of the Publication table in the WHERE clause to only select Book entities.

13:02:22,453 DEBUG [org.hibernate.SQL] - 
    select
        publicatio2_.id as id2_1_,
        publicatio2_.publishingDate as publishi3_1_,
        publicatio2_.title as title4_1_,
        publicatio2_.version as version5_1_,
        publicatio2_.numPages as numPages6_1_,
        publicatio2_.url as url7_1_,
        publicatio2_.DTYPE as DTYPE1_1_ 
    from
        Author author0_ 
    inner join
        PublicationAuthor publicatio1_ 
            on author0_.id=publicatio1_.authorId 
    inner join
        Publication publicatio2_ 
            on publicatio1_.publicationId=publicatio2_.id 
    where
        author0_.firstName='Thorben' 
        and publicatio2_.DTYPE='Book'

Learn more:

If you’re using JPQL, you might also be interested in my detailed guide about it: Ultimate Guide to JPQL Queries with JPA and Hibernate.

And I also wrote a tutorial about JPA’s different strategies to map inheritance hierarchies: Complete Guide: Inheritance strategies with JPA and Hibernate.

Hibernate Tips Book

Get more recipes like this one in my new book Hibernate Tips: More than 70 solutions to common Hibernate problems.

It gives you more than 70 ready-to-use recipes for topics like basic and advanced mappings, logging, Java 8 support, caching, and statically and dynamically defined queries.

Get it now!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.