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>
{ /* ... */ }