diff --git a/src/main/asciidoc/repositories.adoc b/src/main/asciidoc/repositories.adoc index cdb337438..918580efb 100644 --- a/src/main/asciidoc/repositories.adoc +++ b/src/main/asciidoc/repositories.adoc @@ -505,15 +505,16 @@ The preceding approach is not feasible when you want to add a single method to a ==== [source, java] ---- +@NoRepositoryBean public interface MyRepository - extends JpaRepository { + extends PagingAndSortingRepository { void sharedCustomMethod(ID id); } ---- ==== -. Now your individual repository interfaces will extend this intermediate interface instead of the Repository interface to include the functionality declared. +. Now your individual repository interfaces will extend this intermediate interface instead of the `Repository` interface to include the functionality declared. . Next, create an implementation of the intermediate interface that extends the persistence technology-specific repository base class. This class will then act as a custom base class for the repository proxies. + @@ -524,13 +525,12 @@ public interface MyRepository public class MyRepositoryImpl extends SimpleJpaRepository implements MyRepository { - private EntityManager entityManager; + private final EntityManager entityManager; - // There are two constructors to choose from, either can be used. public MyRepositoryImpl(Class domainClass, EntityManager entityManager) { super(domainClass, entityManager); - // This is the recommended method for accessing inherited class dependencies. + // Keep the EntityManager around to used from the newly introduced methods. this.entityManager = entityManager; } @@ -541,49 +541,45 @@ public class MyRepositoryImpl ---- ==== + -The default behavior of the Spring `` namespace is to provide an implementation for all interfaces that fall under the `base-package`. This means that if left in its 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 that extends Repository from being instantiated as a repository instance, you can either annotate it with @NoRepositoryBean or move it outside of the configured `base-package`. +The default behavior of the Spring `` namespace is to provide an implementation for all interfaces that fall under the `base-package`. This means that if left in its 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 that extends `Repository` from being instantiated as a repository instance, you can either annotate it with `@NoRepositoryBean` (as seen above) or move it outside of the configured `base-package`. -. Then 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. +. Then 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 ==== [source, java] ---- -public class MyRepositoryFactoryBean, T, I extends Serializable> - extends JpaRepositoryFactoryBean { - - protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) { +public class MyRepositoryFactoryBean, T, + I extends Serializable> extends JpaRepositoryFactoryBean { - return new MyRepositoryFactory(entityManager); + protected RepositoryFactorySupport createRepositoryFactory(EntityManager em) { + return new MyRepositoryFactory(em); } - private static class MyRepositoryFactory extends JpaRepositoryFactory { + private static class MyRepositoryFactory + extends JpaRepositoryFactory { - private EntityManager entityManager; + private final EntityManager em; - public MyRepositoryFactory(EntityManager entityManager) { - super(entityManager); + public MyRepositoryFactory(EntityManager em) { - this.entityManager = entityManager; + super(em); + this.em = em; } protected Object getTargetRepository(RepositoryMetadata metadata) { - - return new MyRepositoryImpl((Class) metadata.getDomainClass(), entityManager); + return new MyRepositoryImpl((Class) metadata.getDomainClass(), em); } 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; + return MyRepositoryImpl.class; } } } ---- ==== -. Finally, either declare beans of the custom factory directly or use the `factory-class` attribute of the Spring namespace to tell the repository infrastructure to use your custom factory implementation. +. Finally, either declare beans of the custom factory directly or use the `factory-class` attribute of the Spring namespace or `@Enable…` annotation to instruct the repository infrastructure to use your custom factory implementation. + .Using the custom factory with the namespace ==== @@ -593,6 +589,15 @@ public class MyRepositoryFactoryBean, T, I extends factory-class="com.acme.MyRepositoryFactoryBean" /> ---- ==== ++ +.Using the custom factory with the `@Enable…` annotation +==== +[source, java] +---- +@EnableJpaRepositories(factoryClass = "com.acme.MyRepositoryFactoryBean") +class Config {} +---- +==== [[core.extensions]] == Spring Data extensions