diff --git a/src/docbkx/repositories.xml b/src/docbkx/repositories.xml
index 564b8cc6b..f682a6ae1 100644
--- a/src/docbkx/repositories.xml
+++ b/src/docbkx/repositories.xml
@@ -23,6 +23,15 @@
interfaces of Spring Data repositories in general for detailled
information on the specific features of a particular store consult the
later chapters of this document.
+
+
+ As this part of the documentation is pulled in from Spring Data
+ Commons we have to decide for a particular module to be used as example.
+ The configuration and code samples in this chapter are using the JPA
+ module. Make sure you adapt e.g. the XML namespace declaration, types to
+ be extended to the equivalents of the module you're actually
+ using.
+
@@ -664,7 +673,8 @@ UserRepository repository = factory.getRepository(UserRepository.class);
An interface declaring custom shared behaviour
- public interface MyRepository<T, ID extends Serializable>
+
+public interface MyRepository<T, ID extends Serializable>
extends JpaRepository<T, ID> {
void sharedCustomMethod(ID id);
@@ -672,59 +682,93 @@ UserRepository repository = factory.getRepository(UserRepository.class);
Now your individual repository interfaces will extend this
- intermediate interface to include the functionality declared. The second
- step is to create an implementation of this interface that extends the
- persistence technology specific repository base class which will act as
- custom base class for the repository proxies then.
+ intermediate interface instead of the
+ Repository interface to include the
+ functionality declared. The second step is to create an implementation
+ of this interface that extends the persistence technology specific
+ repository base class which will then act as a custom base class for the
+ repository proxies.
- If you're using automatic repository interface detection using
- the Spring namespace using the interface just as is will cause Spring
- to create an instance of MyRepository.
- This is of course not desired as it just acts as intermediary between
- Repository and the actual repository
- interfaces you want to define for each entity. To exclude an interface
- extending Repository from being
- instantiated as repository instance annotate it with
- @NoRepositoryBean.
+ The default behaviour of the Spring <repositories
+ /> namespace is to provide an implementation for all
+ interfaces that fall under the base-package. This means
+ that if left in it's current state, an implementation instance of
+ MyRepository will be created by Spring.
+ This is of course not desired as it is just supposed to act as an
+ intermediary between Repository and the
+ actual repository interfaces you want to define for each entity. To
+ exclude an interface extending
+ Repository from being instantiated as a
+ repository instance it can either be annotate it with
+ @NoRepositoryBean or moved out side of
+ the configured base-package.
Custom repository base class
- public class MyRepositoryImpl<T, ID extends Serializable>
+
+public class MyRepositoryImpl<T, ID extends Serializable>
extends SimpleJpaRepository<T, ID> implements MyRepository<T, ID> {
+ private EntityManager entityManager;
+
+ // There are two constructors to choose from, either can be used.
+ public MyRepositoryImpl(Class<T> domainClass, EntityManager entityManager) {
+ super(domainClass, entityManager);
+
+ // This is the recommended method for accessing inherited class dependencies.
+ this.entityManager = entityManager;
+ }
+
public void sharedCustomMethod(ID id) {
// implementation goes here
}
}
- The last step to get this implementation used as base class for
- Spring Data repositories is replacing the standard
- RepositoryFactoryBean with a custom one using a
- custom RepositoryFactory that in turn creates
- instances of your MyRepositoryImpl class.
+ The last step is to create a custom repository factory to replace
+ the default RepositoryFactoryBean that will in
+ turn produce a custom RepositoryFactory. The new
+ repository factory will then provide your
+ MyRepositoryImpl as the implementation of any
+ interfaces that extend the Repository
+ interface, replacing the SimpleJpaRepository
+ implementation you just extended.
Custom repository factory bean
- public class MyRepositoryFactoryBean<T extends JpaRepository<?, ?>
- extends JpaRepositoryFactoryBean<T> {
+
+public class MyRepositoryFactoryBean<R extends JpaRepository<T, I>, T, I extends Serializable>
+ extends JpaRepositoryFactoryBean<R, T, I> {
- protected RepositoryFactorySupport getRepositoryFactory(…) {
- return new MyRepositoryFactory(…);
+ protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
+
+ return new MyRepositoryFactory(entityManager);
}
- private static class MyRepositoryFactory extends JpaRepositoryFactory{
+ private static class MyRepositoryFactory<T, I extends Serializable> extends JpaRepositoryFactory {
- public MyRepositoryImpl getTargetRepository(…) {
- return new MyRepositoryImpl(…);
+ private EntityManager entityManager;
+
+ public MyRepositoryFactory(EntityManager entityManager) {
+ super(entityManager);
+
+ this.entityManager = entityManager;
}
- public Class<? extends RepositorySupport> getRepositoryClass() {
- return MyRepositoryImpl.class;
+ protected Object getTargetRepository(RepositoryMetadata metadata) {
+
+ return new MyRepositoryImpl<T, I>((Class<T>) metadata.getDomainClass(), entityManager);
+ }
+
+ protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
+
+ // The RepositoryMetadata can be safely ignored, it is used by the JpaRepositoryFactory
+ //to check for QueryDslJpaRepository's which is out of scope.
+ return MyRepository.class;
}
}
}