Oliver Drotbohm opened DATACMNS-29 and commented
Currently the repository abstraction in Spring Data commons is built on top of interfaces that are complemented by store specific ones. The common ones carry typing information that is needed to type some of the CRUD methods. We already have separated out sorting and paging functionality into PagingAndSortingRepository
to allow implementations that only want to provide plain CRUD.
The store specific ones serve two purposes right now: one the one hand they allow the repositories
namespace element to find the interfaces it has to create a store-specific factory bean to back that interface. This is actually only necessary to be safe in scenarios where the user uses multiple datastores and the classpath scanning for JPA potentially finds repositories that should work against Mongo or the other way round. E.g.
public interface UserRepository extends JpaRepository<User, Long> { ... }
public interface PersonRepository extends MongoRepository<Person, ObjectId> { ... }
<jpa:repositories base-package="com.acme.repositories" />
<mongo:repositories base-package="com.acme.repositories" />
In some corners of the store specific implementations we already use interface composition to expose additional API on the repositories. E.g. in the JPA module we have JpaSpecificationExecuter
to allow Criteria API based Specification
objects as well as QueryDslPredicateExecutor
to allow execution of Querydsl Predicate
instances.
Challenges
Users usually hesitate to let their repository interface extend a store specific interface as this leaks store specific API to the clients. If we'd allow simply using extending Repository
or PagingAndSortingRepository
we'd have to refactor the namespace parsers to discover interfaces based on these ones and let the user handle potential store-specific repository overlaps using excludes.
As JpaRepository
also makes the CRUD methods of Repository
transactional we probably have to provide a neutral TransactionalCrudRepository
to the Commons project, as well as one including the paging and sorting methods. This way the number of needed interfaces increases quite a lot.
On the other hand by extending the Repository
interface, users expose quite a few CRUD methods through their repository interface even that might not be desirable. We could move the CRUD methods into a CrudRepository
interface and have the Repository
interface as marker interface only. The typing information (domain and id class) could go into the CRUD one as well although this probably causes some wider scoped internal refactorings as the current codebase currently assumes these information mandatorily being present. Perhaps we could even rather use an annotation then but that would introduce yet another concept to demarcate repository interfaces
Affects: 1.0 M5
Issue Links: