Reputation: 11313
What is the difference between CrudRepository and JpaRepository interfaces in Spring Data JPA?
When I see the examples on the web, I see them there used kind of interchangeably.
Upvotes: 1127
Views: 517897
Reputation: 1316
What is the difference between CrudRepository and JpaRepository interfaces in Spring Data JPA?
Spring Data JPA provides both JpaRepository
and CrudRepository
interfaces to simplify the creation of repositories for data access in JPA-based applications.
CrudRepository
is the base interface for entities with basic CRUD (Create, Read, Update, Delete) operations. CrudRepository
provides a minimal set of methods like save()
, findAll()
, findById()
, delete()
, etc., and can be extended by other custom methods.
It is the code example:
public interface PersonEntityRepository extends CrudRepository<PersonEntity, Long> {
}
JpaRepository
interface extends CrudRepository
interface.
JpaRepository
interface provides other additional methods to the basic CRUD operations provided by CrudRepository such as:
findAll(Sort sort)
- a method which returns all entities sorted by the given criteria.findAll(Pageable pageable)
- a method which returns a Page of entities according to the given pagination and sorting criteria.flush()
- a method which flushes all pending changes to the database.saveAndFlush(T entity)
- a method which saves an entity and immediately flushes changes to the database.
It is the code example:public interface PersonEntityRepository extends JpaRepository<PersonEntity, Long> {
List<TestEntity> findByName(String name);
List<Employee> findByAgeGreaterThan(double age);
}
Why would you want to use one over the other?
Choosing between the two depends on the specific needs of your application. I would recommend to use CrudRepository
interface for basic CRUD operations, and JpaRepository
interface for more advanced functionality such as pagination, sorting, and immediate flushing of changes to the database.
Upvotes: 12
Reputation: 19173
spring-data-jpa 3.x
As of spring-data-jpa 3.x
used with spring-boot 3.x
and spring-core 6.x
,
the structure and the hierarchy has been modified and seems to be more clear.
ListCrudRepository
extends CrudRepository
ListPagingAndSortingRepository
extends PagingAndSortingRepository
JpaRepository
extends both ListCrudRepository
, ListPagingAndSortingRepository
.
So basically the new introduced interfaces of ListPagingAndSortingRepository
, ListCrudRepository
now represent the functionalities of the old interfaces but with returned types of List<T>
while the remaining PagingAndSortingRepository
, CrudRepository
handle the return types of Iterable<T>
In the new (3.x) version the structure is the following:
In the past (before 3.0) many of the declared methods which returned List<T>
have been directly declared inside the JpaRepository
, but now with separate interfaces for those methods they have been extracted into ListPagingAndSortingRepository
, ListCrudRepository
.
So the structure before (3.x) was
I hope it is clear from the above schemas how the mentioned JpaRepository
and CrudRepository
have been modified in 3.x
version.
In case you plan to migrate spring-data-jpa
from 2.x
into 3.x
(would be necessary if you migrate from spring-boot 2.x
to spring-boot 3.x
) as illustrated in the above schemas you should expect to have breaking code in cases where you have used the PagingAndSortingRepository
in your code, as in the past it was extending from CrudRepository
and so your custom repository which extended directly the PagingAndSortingRepository
already had access to the methods of CrudRepository
. If this is the issue you should fix this by adapting your custom repository to also extend either the ListCrudRepository
or the CrudRepository
.
Upvotes: 26
Reputation: 401
Crud Repository is the base interface and it acts as a marker interface.
JPA repository also extends the PagingAndSorting repository. It provides all the method for which are useful for implementing pagination. Crud Repository doesn't provide methods for implementing pagination and sorting
Upvotes: 2
Reputation: 90527
JpaRepository
extends PagingAndSortingRepository
which in turn extends CrudRepository
.
Their main functions are:
CrudRepository
mainly provides CRUD functions.PagingAndSortingRepository
provides methods to do pagination and sorting records.JpaRepository
provides some JPA-related methods such as flushing the persistence context and deleting records in a batch.Because of the inheritance mentioned above, JpaRepository
will have all the functions of CrudRepository
and PagingAndSortingRepository
. So if you don't need the repository to have the functions provided by JpaRepository
and PagingAndSortingRepository
, use CrudRepository
.
Upvotes: 1532
Reputation: 1727
Below are the differences between CrudRepository
and JpaRepository
as:
CrudRepository
CrudRepository
is a base interface and extends the Repository
interface.CrudRepository
mainly provides CRUD (Create, Read, Update, Delete) operations.saveAll()
method is Iterable
.CrudRepository
.JpaRepository
JpaRepository
extends PagingAndSortingRepository
that extends CrudRepository
.JpaRepository
provides CRUD and pagination operations, along with additional methods like flush()
, saveAndFlush()
, and deleteInBatch()
, etc.saveAll()
method is a List
.JpaRepository
.Upvotes: 29
Reputation: 715
All the answers provide sufficient details to the question. However, let me add something more.
Why are we using these Interfaces:
Which interface does what:
When to use which interface:
According to http://jtuts.com/2014/08/26/difference-between-crudrepository-and-jparepository-in-spring-data-jpa/
Generally the best idea is to use CrudRepository or PagingAndSortingRepository depending on whether you need sorting and paging or not.
The JpaRepository should be avoided if possible, because it ties you repositories to the JPA persistence technology, and in most cases you probably wouldn’t even use the extra methods provided by it.
Upvotes: 10
Reputation: 83151
Ken's answer is basically right but I'd like to chime in on the "why would you want to use one over the other?" part of your question.
The base interface you choose for your repository has two main purposes. First, you allow the Spring Data repository infrastructure to find your interface and trigger the proxy creation so that you inject instances of the interface into clients. The second purpose is to pull in as much functionality as needed into the interface without having to declare extra methods.
The Spring Data core library ships with two base interfaces that expose a dedicated set of functionalities:
CrudRepository
- CRUD methodsPagingAndSortingRepository
- methods for pagination and sorting (extends CrudRepository
)The individual store modules (e.g. for JPA or MongoDB) expose store-specific extensions of these base interfaces to allow access to store-specific functionality like flushing or dedicated batching that take some store specifics into account. An example for this is deleteInBatch(…)
of JpaRepository
which is different from delete(…)
as it uses a query to delete the given entities which is more performant but comes with the side effect of not triggering the JPA-defined cascades (as the spec defines it).
We generally recommend not to use these base interfaces as they expose the underlying persistence technology to the clients and thus tighten the coupling between them and the repository. Plus, you get a bit away from the original definition of a repository which is basically "a collection of entities". So if you can, stay with PagingAndSortingRepository
.
The downside of directly depending on one of the provided base interfaces is two-fold. Both of them might be considered as theoretical but I think they're important to be aware of:
Page
or Pageable
in your code anyway. Spring Data is not any different from any other general purpose library like commons-lang or Guava. As long as it provides reasonable benefit, it's just fine.CrudRepository
, you expose a complete set of persistence method at once. This is probably fine in most circumstances as well but you might run into situations where you'd like to gain more fine-grained control over the methods expose, e.g. to create a ReadOnlyRepository
that doesn't include the save(…)
and delete(…)
methods of CrudRepository
.The solution to both of these downsides is to craft your own base repository interface or even a set of them. In a lot of applications I have seen something like this:
interface ApplicationRepository<T> extends PagingAndSortingRepository<T, Long> { }
interface ReadOnlyRepository<T> extends Repository<T, Long> {
// Al finder methods go here
}
The first repository interface is some general purpose base interface that actually only fixes point 1 but also ties the ID type to be Long
for consistency. The second interface usually has all the find…(…)
methods copied from CrudRepository
and PagingAndSortingRepository
but does not expose the manipulating ones. Read more on that approach in the reference documentation.
The repository abstraction allows you to pick the base repository totally driven by you architectural and functional needs. Use the ones provided out of the box if they suit, craft your own repository base interfaces if necessary. Stay away from the store specific repository interfaces unless unavoidable.
Upvotes: 518
Reputation: 11136
Summary:
PagingAndSortingRepository extends CrudRepository
JpaRepository extends PagingAndSortingRepository
The CrudRepository interface provides methods for CRUD operations, so it allows you to create, read, update and delete records without having to define your own methods.
The PagingAndSortingRepository provides additional methods to retrieve entities using pagination and sorting.
Finally the JpaRepository add some more functionality that is specific to JPA.
Upvotes: 125