Meilleure façon de gérer l'héritage des entités dans Spring Data JPA
J'ai trois entité JPA classes A
, B
et C
, avec la hiérarchie suivante:
A
|
+---+---+
| |
C B
C'est-à-dire:
@Entity
@Inheritance
public abstract class A { /* ... */ }
@Entity
public class B extends A { /* ... */ }
@Entity
public class C extends A { /* ... */ }
En utilisant Spring Data JPA , Quelle est la meilleure façon d'écrire des référentiels classes pour de telles entités?
Je sais que je peux écrire ceci:
public interface ARespository extends CrudRepository<A, Long> { }
public interface BRespository extends CrudRepository<B, Long> { }
public interface CRespository extends CrudRepository<C, Long> { }
, Mais si dans la classe A
il y a un champ name
et j'ajoute cette méthode dans le ARepository
:
public A findByName(String name);
Je dois écrire une telle méthode aussi dans les deux autres les référentiels, et c'est un peu ennuyeux.. Est-il une meilleure façon de gérer une telle situation?
Un autre point que j'aimerais avoir est que ARespository
devrait être un référentiel en lecture seule (c'est-à-dire étendre la classe Repository
) tandis que les deux autres référentiels devraient exposer toutes les opérations CRUD.
Faites-moi savoir les solutions possibles.
1 réponses
J'ai utilisé la solution également décrite dans ce post du blog de Netgloo.
L'idée est de créer une classe de référentielGénérique comme suit:
@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.
// ...
}
Alors je peux écrire les trois dépôts de cette façon:
@Transactional
public interface ARepository extends ABaseRepository<A> { /* ... */ }
@Transactional
public interface BRepository extends ABaseRepository<B> { /* ... */ }
@Transactional
public interface CRepository extends ABaseRepository<C> { /* ... */ }
De plus, pour obtenir un référentiel en lecture seule pour ARepository
je peux définir le ABaseRepository
en lecture seule:
@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);
}
Et à partir de BRepository
étendre également les données de printemps JPA CrudRepository
pour obtenir un référentiel en lecture / écriture:
@Transactional
public interface BRepository
extends ABaseRepository<B>, CrudRepository<B, Long>
{ /* ... */ }