Best way of handling entities inheritance in Spring Data JPA
I used the solution also described in this post from Netgloo's blog.
The idea is to create a generic repository class like the following:
@NoRepositoryBean
public interface ABaseRepository<T extends A>
extends CrudRepository<T, Long> {
// All methods in this repository will be available in the ARepository,
// in the BRepository and in the CRepository.
// ...
}
then I can write the three repositories in this way:
@Transactional
public interface ARepository extends ABaseRepository<A> { /* ... */ }
@Transactional
public interface BRepository extends ABaseRepository<B> { /* ... */ }
@Transactional
public interface CRepository extends ABaseRepository<C> { /* ... */ }
Moreover, to obtain a read-only repository for ARepository
I can define the ABaseRepository
as read-only:
@NoRepositoryBean
public interface ABaseRepository<T>
extends Repository<T, Long> {
T findOne(Long id);
Iterable<T> findAll();
Iterable<T> findAll(Sort sort);
Page<T> findAll(Pageable pageable);
}
and from BRepository
extend also the Spring Data JPA's CrudRepository
to achieve a read/write repository:
@Transactional
public interface BRepository
extends ABaseRepository<B>, CrudRepository<B, Long>
{ /* ... */ }
Andrea
Updated on July 16, 2022Comments
-
Andrea almost 2 years
I've three JPA entity classes
A
,B
andC
with the following hierarchy:A | +---+---+ | | C B
That is:
@Entity @Inheritance public abstract class A { /* ... */ } @Entity public class B extends A { /* ... */ } @Entity public class C extends A { /* ... */ }
Using Spring Data JPA, what is the best way to write repositories classes for such entities?
I know that I can write these:
public interface ARespository extends CrudRepository<A, Long> { } public interface BRespository extends CrudRepository<B, Long> { } public interface CRespository extends CrudRepository<C, Long> { }
but if in the class
A
there is a fieldname
and I add this method in theARepository
:public A findByName(String name);
I've to write such method also in the other two repositories, and this is a bit annoying.. Is there a better way to handle such situation?
Another point I would like to have is that
ARespository
should be a read-only repository (i.e. extend theRepository
class) while the other two repositories should expose all the CRUD operations.Let me know possible solutions.
-
ALM almost 8 yearsIn this example can you use use repository B to set attributes belonging to Class A that is extended by Class B? I wanted to use a system like this to update B via a spring-data-rest controller.
-
Andrea almost 8 years@ALM I'm pretty sure you can do it. Did you tried it?
-
ALM almost 8 yearsYes I am about to try right now. I am actually debating how I want to set it up but I think I will create a very simple test first then run that to see. I read the other article and after that I believe it should inherit what is for repository A and then be able to be used by B. A would also be setup as read-only
-
Soumitri Pattnaik over 4 years@ALM did you find a proper solution? I am also having a similar case where I want the child class repos for writes and the parent class repo just for reads such as GET ALL (including child entities). I also want to do it the way spring-data-rest does it, is there a way?