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

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!


Related Articles

Responses

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.

Black Friday & Launch Offer: Join the Persistence Hub!

Hi and welcome!

To make sure I provide you with the best content, please tell me what you are looking for.