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.

37
demandé sur Andrea 2014-12-18 12:57:22

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> 
{ /* ... */ }
46
répondu Andrea 2016-02-03 10:44:26