diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/repository/Repository.java b/spring-data-commons-core/src/main/java/org/springframework/data/repository/Repository.java
index cdb2ad294..46c0c4aee 100644
--- a/spring-data-commons-core/src/main/java/org/springframework/data/repository/Repository.java
+++ b/spring-data-commons-core/src/main/java/org/springframework/data/repository/Repository.java
@@ -3,7 +3,16 @@ package org.springframework.data.repository;
import java.io.Serializable;
/**
- *
+ * Central repository marker interface. Captures the domain type to manage as well as the domain type's id type. General
+ * purpose is to hold type information as well as being able to discover interfaces that extend this one during
+ * classpath scanning for easy Spring bean creation.
+ *
+ * Domain repositories extending this interface can selectively expose CRUD methods by simply declaring methods of the
+ * same signature as those declared in {@link CrudRepository}.
+ *
+ * @see CrudRepository
+ * @param the domain type the repository manages
+ * @param the type of the id of the entity the repository manages
* @author Oliver Gierke
*/
public interface Repository {
diff --git a/src/docbkx/repositories.xml b/src/docbkx/repositories.xml
index d2117bde1..865dcc296 100644
--- a/src/docbkx/repositories.xml
+++ b/src/docbkx/repositories.xml
@@ -29,8 +29,11 @@
The central interface in Spring Data repository abstraction is
Repository (probably not that much of a
surprise). It is typeable to the domain class to manage as well as the id
- type of the domain class and provides some sophisticated functionality
- around CRUD for the entity managed.
+ type of the domain class. This interface mainly acts as marker interface
+ to capture the types to deal with and helps us discovering interface that
+ extend this one. Beyond that there's
+ CrudRepository which provides some
+ sophisticated functionality around CRUD for the entity managed.
Repository interface
@@ -43,8 +46,6 @@
-
-
@@ -52,15 +53,13 @@
- public interface Repository<T, ID extends Serializable> {
+ public interface CrudRepository<T, ID extends Serializable> {
T save(T entity);
- T findById(ID primaryKey);
+ T findOne(ID primaryKey);
- List<T> findAll();
-
- Page<T> findAll(Pageable pageable);
+ Iterable<T> findAll();
Long count();
@@ -84,10 +83,6 @@
Returns all entities.
-
- Returns a page of entities.
-
-
Returns the number of entities.
@@ -108,23 +103,23 @@
implementations for a variety of Spring Data modules that implement that
interface.
- On top of the Repository there is a PagingAndSortingRepository
- abstraction that adds additional methods to ease paginated access to
- entities:
+ On top of the CrudRepository there is
+ a PagingAndSortingRepository abstraction
+ that adds additional methods to ease paginated access to entities:
PagingAndSortingRepository
public interface PagingAndSortingRepository<T, ID extends Serializable> extends Repository<T, ID> {
- List<T> findAll(Sort sort);
+ Iterable<T> findAll(Sort sort);
Page<T> findAll(Pageable pageable);
}
- Accessing the second page of User by a page size of 20 you could
- simply do something like this:
+ Accessing the second page of User by a page
+ size of 20 you could simply do something like this:
PagingAndSortingRepository<User, Long> repository = // … get access to a bean
Page<User> users = repository.findAll(new PageRequest(1, 20);
@@ -135,16 +130,15 @@ Page<User> users = repository.findAll(new PageRequest(1, 20);Next to standard CRUD functionality repositories are usually query
the underlying datastore. With Spring Data declaring those queries becomes
- a four-step process (we use the JPA based module as example but that works
- the same way for other stores):
+ a four-step process.
- Declare an interface extending the technology specific
- Repository sub-interface and type it to the domain class it shall
- handle.
+ Declare an interface extending
+ Repository or one of it's
+ sub-interfaces and type it to the domain class it shall handle.
- public interface PersonRepository extends JpaRepository<User, Long> { … }
+ public interface PersonRepository extends Repository<User, Long> { … }
@@ -194,10 +188,52 @@ Page<User> users = repository.findAll(new PageRequest(1, 20);Defining repository interfaces
As a very first step you define a domain class specific repository
- interface to start with. It's got to be typed to the domain class and an
- ID type so that you get CRUD methods of the
- Repository interface tailored to
- it.
+ interface to start with. It's got to extend
+ Repository and be typed to the domain
+ class and an ID type. If you want to expose CRUD methods for that domain
+ type, extend CrudRepository instead of
+ Repository.
+
+
+ Fine tuning repository definition
+
+ Usually you will have your repository interface extend
+ Repository,
+ CrudRepository or
+ PagingAndSortingRepository. If you
+ don't like extending Spring Data interfaces at all you can also
+ annotate your repository interface with
+ @RepositoryDefinition. Extending
+ CrudRepository will expose a complete
+ set of methods to manipulate your entities. If you rather want to be
+ selective about the methods being expose simply copy the ones you want
+ to expose from CrudRepository into your
+ domain repository.
+
+
+ Selectively exposing CRUD methods
+
+ interface MyBaseRepository<T, ID extends Serializable> extends Repository<T, ID> {
+ T findOne(ID id);
+ T save(T entity);
+}
+
+interface UserRepository extends MyBaseRepository<User, Long> {
+
+ User findByEmailAddress(EmailAddress emailAddress);
+}
+
+
+ In the first step we define a common base interface for all our
+ domain repositories and expose findOne(…) as
+ well as save(…).These methods will be routed
+ into the base repository implementation of the store of your choice
+ because they are matching the method signatures in
+ CrudRepository. So our
+ UserRepository will now be able to save
+ users, find single ones by id as well as triggering a query to find
+ Users by their email address.
+
@@ -271,7 +307,7 @@ Page<User> users = repository.findAll(new PageRequest(1, 20);
Query creation from method names
- public interface PersonRepository extends JpaRepository<User, Long> {
+ public interface PersonRepository extends Repository<User, Long> {
List<Person> findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);
}
@@ -398,10 +434,9 @@ List<User> findByLastname(String lastname, Pageable pageable);In this case we instruct Spring to scan
com.acme.repositories and all it's sub packages for
- interfaces extending the appropriate
- Repository sub-interface (in this case
- JpaRepository). For each interface
- found it will register the presistence technology specific
+ interfaces extending Repository or one
+ of its sub-interfaces. For each interface found it will register the
+ presistence technology specific
FactoryBean to create the according
proxies that handle invocations of the query methods. Each of these
beans will be registered under a bean name that is derived from the
@@ -520,7 +555,7 @@ UserRepository repository = factory.getRepository(UserRepository.class);
Changes to the your basic repository interface
- public interface UserRepository extends JpaRepository<User, Long>, UserRepositoryCustom {
+ public interface UserRepository extends CrudRepository<User, Long>, UserRepositoryCustom {
// Declare query methods here
}Let your standard repository interface extend the custom