Until M2 of Spring Data we required users to extend JpaRepository
due to the following reasons:
- The classpath scanning infrastructure only picked up interfaces extending that interface as one might use Spring Data JPA and Spring Data Mongo in parallel and have both of them pointed to the very same package it would not be clear which store to create the proxy for. However since RC1 we simply leave that burden to the developer as we think it's a rather exotic case and the benefit of just using
Repository
, CrudRepository
or the like outweights the effort you have to take in the just described corner case. You can use exclude
and include
elements in the namespace to gain finer-grained control over this.
- Until M2 we had transactionality applied to the CRUD methods by redeclaring the CRUD methods and annotating them with
@Transactional
. This decision in turn was driven by the algorithm AnnotationTransactionAttributeSource
uses to find transaction configuration. As we wanted to provide the user with the possibility to reconfigure transactions by just redeclaring a CRUD method in the concrete repository interface and applying @Transactional
on it. For RC1 we decided to implement a custom TransactionAttributeSource
to be able to move the annotations back to the repository CRUD implementation.
Long story short, here's what it boils down to:
As of RC1 there's no need to extend the store specific repository interface anymore, except you want to…
- Use
List
-based access to findAll(…)
instead of the Iterable
-based one in the more core repository interfaces (allthough you could simply redeclare the relevant methods in a common base interface to return List
s as well)
- You want to make use of the JPA-specific methods like
saveAndFlush(…)
and so on.
Generally you are much more flexible regarding the exposure of CRUD methods since RC1 as you can even only extend the Repository
marker interface and selectively add the CRUD methods you want to expose. As the backing implementation will still implement all of the methods of PagingAndSortingRepository
we can still route the calls to the instance:
public interface MyBaseRepository<T, ID extends Serializable> extends Repository<T, ID> {
List<T> findAll();
T findOne(ID id);
}
public interface UserRepository extends MyBaseRepository<User, Long> {
List<T> findByUsername(String username);
}
In that example we define MyBaseRepository
to only expose findAll()
and findOne(…)
(which will be routed into the instance implementing the CRUD methods) and the concrete repository adding a finder method to the two CRUD ones.
For more details on that topic please consult the reference documentation.