Querying Object Children in Hibernate

In our example we want to retrieve Users that are assigned a particular Authority, like role_admin, role_user, etc. We need to include ALL Authorities of the User. Expressed another way, we want all Parent data and all Child Objects, but only Parent Objects with a given Child.

Our User table has a @ManyToMany relationship with Authorities through a user_authorities table.

In our User Model we define the @ManyToMany with FetchType.EAGER because we always want our Authorities contained in our User object.

If we want all child objects in a @Query statement we would normally include a fetch directive, like so.

But when we want to retrieve all users that are assigned ROLE_USER with the above query we would retrieve all User data for the user object but only the ROLE_USER Authority. Our Admin User would as a result of this query appear to be assigned the ROLE_USER Authority only.

We could do a userRepository.findAll() and then filter out the users containing our role with a Java Stream.

But there's a much more simple approach by letting Hibernate do its thing. Because we defined the @ManyToMany relationship of Users to Authorities as EAGER, we already have the Child Objects at our disposal. Instead of performing a fresh fetch on the Child Objects for authority_id = id, we're essentially querying our Persistence Context. (No left join fetch.)

This retrieves what we want: All users, including ALL of their authorities, who are assigned a given authority by id. And cleaner Controller code as well. No streaming required.

As a bonus bit of code, if you're interested in the task at hand of deleting a ROLE and removing its assignment to any User prior to its deletion, here is the Service method.

Source Code Notes for this Post

All source code discussed in this post can be found in my NixMash Spring GitHub repo and viewed online here.

Posted April 14, 2016 12:15 PM EDT

More Like This Post