mkyong jparepository example data java spring spring-data spring-boot spring-data-jpa

java - jparepository - La mejor forma de manejar la herencia de entidades en Spring Data JPA



spring jpa hibernate (1)

Tengo tres clases de entidad JPA A , B y C con la siguiente jerarquía:

A | +---+---+ | | C B

Es decir:

@Entity @Inheritance public abstract class A { /* ... */ } @Entity public class B extends A { /* ... */ } @Entity public class C extends A { /* ... */ }

Usando Spring Data JPA , ¿cuál es la mejor manera de escribir clases de repositorios para tales entidades?

Sé que puedo escribir esto:

public interface ARespository extends CrudRepository<A, Long> { } public interface BRespository extends CrudRepository<B, Long> { } public interface CRespository extends CrudRepository<C, Long> { }

pero si en la clase A hay un name campo y agrego este método en el ARepository :

public A findByName(String name);

Tengo que escribir ese método también en los otros dos repositorios, y esto es un poco molesto ... ¿Hay una mejor manera de manejar esa situación?

Otro punto que me gustaría tener es que ARespository debe ser un repositorio de solo lectura (es decir, extender la clase Repository ) mientras que los otros dos repositorios deben exponer todas las operaciones CRUD.

Déjame saber posibles soluciones.


Usé la solución también descrita en esta publicación del blog de Netgloo.

La idea es crear una clase de repositorio genérico como la siguiente:

@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. // ... }

entonces puedo escribir los tres repositorios de esta manera:

@Transactional public interface ARepository extends ABaseRepository<A> { /* ... */ } @Transactional public interface BRepository extends ABaseRepository<B> { /* ... */ } @Transactional public interface CRepository extends ABaseRepository<C> { /* ... */ }

Además, para obtener un repositorio de solo lectura para ARepository , puedo definir ABaseRepository como de solo lectura:

@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); }

y desde BRepository extienden también el BRepository Spring Data JPA para lograr un repositorio de lectura / escritura:

@Transactional public interface BRepository extends ABaseRepository<B>, CrudRepository<B, Long> { /* ... */ }