Handling entities inheritance with Spring Data JPA

Suppose to have three JPA entities, say User, Person and Company, where the last two extends (inherits by) the first one:

  |           |
Person     Company

that is:

public abstract class User { 
  private long id;

  private String email;

  // ...

public class Person extends User { /* ... */ }

public class Company extends User { /* ... */ }

We want to write three Repository classes (aka DAO), one for each entity, following the hierarchy structure so all repository’s methods referring the base class User (for example a method findByEmail) are available on all repositories but written only once.

So, we start writing a generic user repository class:

public interface UserBaseRepository<T extends User> 
extends CrudRepository<T, Long> {

  public T findByEmail(String email);

All methods in this repository will be available in the UserRepository, in the PersonRepository and in the CompanyRepository.

Then we define repositories for the three entities:

public interface UserRepository extends UserBaseRepository<User> { /* ... */ }

public interface PersonRepository extends UserBaseRepository<Person> { /* ... */ }

public interface CompanyRepository extends UserBaseRepository<Company> { /* ... */ }

That’s all!

Some Tips

Referring the right entity type in the base repository

In the base repository you can referring the actual entity type inside a custom query (@Query annotation) using the #{#entityName} SpEL variable, for example:

public interface UserBaseRepository 
extends CrudRepository<T, Long> {

  @Query("select u from #{#entityName} as u where u.email = ?1 ")
  T findByEmail(String email);


The value of #{#entityName} will be the entity type T.

Read-only repository for User class

To obtain a read-only repository for the User class we can define the UserBaseRepository as read-only:

public interface UserBaseRepository<T> 
extends Repository<T, Long> {
  T findOne(Long id);
  Iterable<T> findAll();
  Iterable<T> findAll(Sort sort);
  Page<T> findAll(Pageable pageable);

and from PersonRepository (and CompanyRepository) extend also the Spring Data JPA’s CrudRepository to achieve a read/write repository:

public interface PersonRepository 
extends UserBaseRepository<B>, CrudRepository<B, Long> 
{ /* ... */ }

Try yourself

Get a working example using the code described above from our GitHub repository here:



  • mrts

    Thanks for sharing!

  • Augusto Santos

    Thanks, it’s a perfect tutorial. I have a question. Can I replace CrudRepository by JpaRepository in the UserBaseRepository class? What’s the difference between them?

  • Данил Ходырев

    How I can get User by id?

  • Vishal Wagh

    Nice Article. How do i get report from multiple class. Lets say, i want retrieve data from User, Person & Company tables, using some custom queries & map to one of the custom bean.
    Please suggest some approach.

  • Armando Suárez Pons

    Dear Andrea, very good article, but polymorphism is not solved. When I try to create a child class tells me that the parent does not have that attribute

  • Roland

    Thanks for this great post!

    At “Read-only repository for User class” – I guess you should extend ReadOnlyRepository instead of Repository, isn’t it?

    • Roland

      Sorry, there is no ReadOnlyRepository :). Your exaple is correct.

  • Daniele Palladino

    Thanks for all, I have only one question for you.
    I have a custom query and I haven’t the dtype information. I must create a DTO Class and verify with an instanceof istruction to determinate the dtype?

  • suman biswas

    facing this issue
    org.springframework.data.mapping.PropertyReferenceException: No property findOne found for type

  • Achraf Smlali

    thank you for the tuto .
    after doing the same in my controller i called personRepository.findAll() to get all persons but in result i got also companies


Category BootstrapCategory CoffeescriptCategory DrupalCategory GravCategory HTMLCategory JavascriptCategory JoomlaCategory jQueryCategory LaravelCategory MagentoCategory PHPCategory SharePointCategory SpringCategory ThymeleafCategory WordPressCategory Workflow


Developed and designed by Netgloo
© 2019 Netgloo