Skip to content

Commit 7da5f5b

Browse files
committed
DATACMNS-649 - Fixed detail in reference docs on extending all repositories.
The custom factory created to extend all repositories with additional behavior needs to return the type of the custom repository base class from getRepositoryBaseClass(…) to make sure the infrastructure can use it to inspect the CRUD methods correctly. Previously the documentations showed an interface being returned. Code formatting in the example and inline code highlighting.
1 parent 0e35fb8 commit 7da5f5b

File tree

1 file changed

+29
-24
lines changed

1 file changed

+29
-24
lines changed

src/main/asciidoc/repositories.adoc

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -505,15 +505,16 @@ The preceding approach is not feasible when you want to add a single method to a
505505
====
506506
[source, java]
507507
----
508+
@NoRepositoryBean
508509
public interface MyRepository<T, ID extends Serializable>
509-
extends JpaRepository<T, ID> {
510+
extends PagingAndSortingRepository<T, ID> {
510511
511512
void sharedCustomMethod(ID id);
512513
}
513514
----
514515
====
515516

516-
. Now your individual repository interfaces will extend this intermediate interface instead of the Repository interface to include the functionality declared.
517+
. Now your individual repository interfaces will extend this intermediate interface instead of the `Repository` interface to include the functionality declared.
517518

518519
. 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.
519520
+
@@ -524,13 +525,12 @@ public interface MyRepository<T, ID extends Serializable>
524525
public class MyRepositoryImpl<T, ID extends Serializable>
525526
extends SimpleJpaRepository<T, ID> implements MyRepository<T, ID> {
526527
527-
private EntityManager entityManager;
528+
private final EntityManager entityManager;
528529
529-
// There are two constructors to choose from, either can be used.
530530
public MyRepositoryImpl(Class<T> domainClass, EntityManager entityManager) {
531531
super(domainClass, entityManager);
532532
533-
// This is the recommended method for accessing inherited class dependencies.
533+
// Keep the EntityManager around to used from the newly introduced methods.
534534
this.entityManager = entityManager;
535535
}
536536
@@ -541,49 +541,45 @@ public class MyRepositoryImpl<T, ID extends Serializable>
541541
----
542542
====
543543
+
544-
The default behavior 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 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`.
544+
The default behavior 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 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`.
545545

546-
. 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.
546+
. 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.
547547
+
548548
.Custom repository factory bean
549549
====
550550
[source, java]
551551
----
552-
public class MyRepositoryFactoryBean<R extends JpaRepository<T, I>, T, I extends Serializable>
553-
extends JpaRepositoryFactoryBean<R, T, I> {
554-
555-
protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
552+
public class MyRepositoryFactoryBean<R extends JpaRepository<T, I>, T,
553+
I extends Serializable> extends JpaRepositoryFactoryBean<R, T, I> {
556554
557-
return new MyRepositoryFactory(entityManager);
555+
protected RepositoryFactorySupport createRepositoryFactory(EntityManager em) {
556+
return new MyRepositoryFactory(em);
558557
}
559558
560-
private static class MyRepositoryFactory<T, I extends Serializable> extends JpaRepositoryFactory {
559+
private static class MyRepositoryFactory<T, I extends Serializable>
560+
extends JpaRepositoryFactory {
561561
562-
private EntityManager entityManager;
562+
private final EntityManager em;
563563
564-
public MyRepositoryFactory(EntityManager entityManager) {
565-
super(entityManager);
564+
public MyRepositoryFactory(EntityManager em) {
566565
567-
this.entityManager = entityManager;
566+
super(em);
567+
this.em = em;
568568
}
569569
570570
protected Object getTargetRepository(RepositoryMetadata metadata) {
571-
572-
return new MyRepositoryImpl<T, I>((Class<T>) metadata.getDomainClass(), entityManager);
571+
return new MyRepositoryImpl<T, I>((Class<T>) metadata.getDomainClass(), em);
573572
}
574573
575574
protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
576-
577-
// The RepositoryMetadata can be safely ignored, it is used by the JpaRepositoryFactory
578-
//to check for QueryDslJpaRepository's which is out of scope.
579-
return MyRepository.class;
575+
return MyRepositoryImpl.class;
580576
}
581577
}
582578
}
583579
----
584580
====
585581

586-
. 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.
582+
. 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.
587583
+
588584
.Using the custom factory with the namespace
589585
====
@@ -593,6 +589,15 @@ public class MyRepositoryFactoryBean<R extends JpaRepository<T, I>, T, I extends
593589
factory-class="com.acme.MyRepositoryFactoryBean" />
594590
----
595591
====
592+
+
593+
.Using the custom factory with the `@Enable…` annotation
594+
====
595+
[source, java]
596+
----
597+
@EnableJpaRepositories(factoryClass = "com.acme.MyRepositoryFactoryBean")
598+
class Config {}
599+
----
600+
====
596601

597602
[[core.extensions]]
598603
== Spring Data extensions

0 commit comments

Comments
 (0)