¿Cuál es la diferencia entre las interfaces CrudRepository y JpaRepository en Spring Data JPA?

Resuelto kseeker asked hace 11 años • 9 respuestas

¿Cuál es la diferencia entre las interfaces CrudRepository y JpaRepository en Spring Data JPA ?

Cuando veo los ejemplos en la web, veo que se usan indistintamente.

  1. ¿Cuál es la diferencia entre ellos?
  2. ¿Por qué querrías usar uno sobre el otro?
kseeker avatar Dec 24 '12 02:12 kseeker
Aceptado

JpaRepositoryse extiende PagingAndSortingRepositoryque a su vez se extiende CrudRepository.

Sus principales funciones son:

  • CrudRepositoryProporciona principalmente funciones CRUD.
  • PagingAndSortingRepositoryproporciona métodos para paginar y ordenar registros.
  • JpaRepositoryproporciona algunos métodos relacionados con JPA, como vaciar el contexto de persistencia y eliminar registros en un lote.

Debido a la herencia mencionada anteriormente, JpaRepositorytendrá todas las funciones de CrudRepositoryy PagingAndSortingRepository. Entonces, si no necesita que el repositorio tenga las funciones proporcionadas por JpaRepositoryy PagingAndSortingRepository, use CrudRepository.

Ken Chan avatar Dec 24 '2012 19:12 Ken Chan

La respuesta de Ken es básicamente correcta, pero me gustaría comentar "¿por qué querrías usar uno sobre el otro?" parte de tu pregunta.

Lo esencial

La interfaz base que elija para su repositorio tiene dos propósitos principales. Primero, permite que la infraestructura del repositorio de Spring Data encuentre su interfaz y active la creación del proxy para que pueda inyectar instancias de la interfaz en los clientes. El segundo propósito es incorporar tanta funcionalidad como sea necesaria en la interfaz sin tener que declarar métodos adicionales.

Las interfaces comunes

La biblioteca central de Spring Data se entrega con dos interfaces básicas que exponen un conjunto dedicado de funcionalidades:

  • CrudRepository- métodos CRUD
  • PagingAndSortingRepository- métodos de paginación y clasificación (extiende CrudRepository)

Interfaces específicas de la tienda

Los módulos de tienda individuales (por ejemplo, para JPA o MongoDB) exponen extensiones específicas de la tienda de estas interfaces base para permitir el acceso a funcionalidades específicas de la tienda, como descarga o procesamiento por lotes dedicado que tienen en cuenta algunas características específicas de la tienda. Un ejemplo de esto es diferente de deleteInBatch(…)ya que utiliza una consulta para eliminar las entidades dadas, lo cual es más eficaz pero tiene el efecto secundario de no activar las cascadas definidas por JPA (como lo define la especificación).JpaRepositorydelete(…)

Generalmente recomendamos no utilizar estas interfaces base, ya que exponen la tecnología de persistencia subyacente a los clientes y, por lo tanto, refuerzan el acoplamiento entre ellos y el repositorio. Además, te alejas un poco de la definición original de repositorio, que es básicamente "una colección de entidades". Entonces, si puedes, quédate con PagingAndSortingRepository.

Interfaces base de repositorio personalizadas

La desventaja de depender directamente de una de las interfaces base proporcionadas es doble. Ambos podrían considerarse teóricos, pero creo que es importante tenerlos en cuenta:

  1. Dependiendo de la interfaz del repositorio de Spring Data, se acopla la interfaz del repositorio a la biblioteca. No creo que este sea un problema particular ya que probablemente usarás abstracciones como Pageo Pageableen tu código de todos modos. Spring Data no es diferente de cualquier otra biblioteca de propósito general como commons-lang o Guava. Mientras proporcione un beneficio razonable, está bien.
  2. Al extender, por ejemplo CrudRepository, expone un conjunto completo de métodos de persistencia a la vez. Probablemente esto también esté bien en la mayoría de las circunstancias, pero es posible que se encuentre con situaciones en las que le gustaría obtener un control más detallado sobre los métodos expuestos, por ejemplo, para crear un archivo ReadOnlyRepositoryque no incluya los métodos save(…)y delete(…)de CrudRepository.

La solución a ambas desventajas es crear su propia interfaz de repositorio base o incluso un conjunto de ellas. En muchas aplicaciones he visto algo como esto:

interface ApplicationRepository<T> extends PagingAndSortingRepository<T, Long> { }

interface ReadOnlyRepository<T> extends Repository<T, Long> {

  // Al finder methods go here
}

La primera interfaz del repositorio es una interfaz base de propósito general que en realidad solo corrige el punto 1 pero también vincula el tipo de ID para mantener Longla coherencia. La segunda interfaz generalmente tiene todos los find…(…)métodos copiados CrudRepositorypero PagingAndSortingRepositoryno expone los manipuladores. Lea más sobre ese enfoque en la documentación de referencia .

Resumen - tl; dr

La abstracción del repositorio le permite elegir el repositorio base totalmente basado en sus necesidades arquitectónicas y funcionales. Utilice los que se proporcionan de fábrica si le convienen, cree sus propias interfaces base de repositorio si es necesario. Manténgase alejado de las interfaces de repositorio específicas de la tienda a menos que sea inevitable.

Oliver Drotbohm avatar Dec 26 '2013 11:12 Oliver Drotbohm