Skip to content

Commit c760465

Browse files
mp911dechristophstrobl
authored andcommitted
DATACMNS-830, DATACMNS-726 - Document using Repositories with multiple Spring Data modules.
Original Pull Request: #158
1 parent e0b9ea5 commit c760465

File tree

1 file changed

+109
-0
lines changed

1 file changed

+109
-0
lines changed

src/main/asciidoc/repositories.adoc

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,115 @@ In this first step you defined a common base interface for all your domain repos
211211

212212
NOTE: Note, that the intermediate repository interface is annotated with `@NoRepositoryBean`. Make sure you add that annotation to all repository interfaces that Spring Data should not create instances for at runtime.
213213

214+
215+
[[repositories.multiple-modules]]
216+
=== Using Repositories with multiple Spring Data modules
217+
218+
Using a unique Spring Data module in your application makes things simple hence, all repository interfaces in the defined scope are bound to the Spring Data module. Sometimes applications require using more than one Spring Data module. In such case, it's required for a repository definition to distinguish between persistence technologies. Spring Data enters strict repository configuration mode because it detects multiple repository factories on the class path. Strict configuration requires details on the repository or the domain class to decide about Spring Data module binding for a repository definition:
219+
220+
1. If the repository definition <<repositories.multiple-modules.types,extends the module-specific repository>>, then it's a valid candidate for the particular Spring Data module.
221+
2. If the domain class is <<repositories.multiple-modules.annotations,annotated with the module-specific type annotation>>, then it's a valid candidate for the particular Spring Data module. Spring Data modules accept either 3rd party annotations (such as JPA's `@Entity`) or provide own annotations such as `@Document` for Spring Data MongoDB/Spring Data Elasticsearch.
222+
223+
[[repositories.multiple-modules.types]]
224+
.Repository definitions using Module-specific Interfaces
225+
====
226+
[source, java]
227+
----
228+
interface MyRepository extends JpaRepository<User, Long> { }
229+
230+
@NoRepositoryBean
231+
interface MyBaseRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
232+
233+
}
234+
235+
interface UserRepository extends MyBaseRepository<User, Long> {
236+
237+
}
238+
----
239+
`MyRepository` and `UserRepository` extend `JpaRepository` in their type hierarchy. They are valid candidates for the Spring Data JPA module.
240+
====
241+
242+
.Repository definitions using generic Interfaces
243+
====
244+
[source, java]
245+
----
246+
interface AmbiguousRepository extends Repository<User, Long> {
247+
248+
}
249+
250+
@NoRepositoryBean
251+
interface MyBaseRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
252+
253+
}
254+
255+
interface AmbiguousUserRepository extends MyBaseRepository<User, Long> {
256+
257+
}
258+
----
259+
`AmbiguousRepository` and `AmbiguousUserRepository` extend only `Repository` and `CrudRepository` in their type hierarchy. While this is perfectly fine using a unique Spring Data module, multiple modules cannot distinguish to which particular Spring Data these repositories should be bound.
260+
====
261+
262+
[[repositories.multiple-modules.annotations]]
263+
.Repository definitions using Domain Classes with Annotations
264+
====
265+
[source, java]
266+
----
267+
interface PersonRepository extends Repository<Person, Long> {
268+
269+
}
270+
271+
@Entity
272+
public class Person {
273+
274+
}
275+
276+
interface UserRepository extends Repository<User, Long> {
277+
278+
}
279+
280+
@Document
281+
public class User {
282+
283+
}
284+
----
285+
`PersonRepository` references `Person` which is annotated with the JPA annotation `@Entity` so this repository clearly belongs to Spring Data JPA. `UserRepository` uses `User` annotated with Spring Data MongoDB's `@Document` annotation.
286+
====
287+
288+
.Repository definitions using Domain Classes with mixed Annotations
289+
====
290+
[source, java]
291+
----
292+
interface JpaPersonRepository extends Repository<Person, Long> {
293+
294+
}
295+
296+
interface MongoDBPersonRepository extends Repository<Person, Long> {
297+
298+
}
299+
300+
@Entity
301+
@Document
302+
public class Person {
303+
304+
}
305+
----
306+
This example shows a domain class using both JPA and Spring Data MongoDB annotations. It defines two repositories, `JpaPersonRepository` and `MongoDBPersonRepository`. One is intended for JPA and the other for MongoDB usage. Spring Data is no longer able to tell the repositories apart which leads to undefined behavior.
307+
====
308+
309+
<<repositories.multiple-modules.types,Repository type details>> and <<repositories.multiple-modules.annotations,identifying domain class annotations>> are used for strict repository configuration identify repository candidates for a particular Spring Data module. Using multiple persistence technology-specific annotations on the same domain type is possible to reuse domain types across multiple persistence technologies, but then Spring Data is no longer able to determine a unique module to bind the repository.
310+
311+
The last way to distinguish repositories is scoping repository base packages. Base packages define the starting points for scanning for repository interface definitions which implies to have repository definitions located in the appropriate packages. By default, annotation-driven configuration uses the package of the configuration class. The <<repositories.create-instances.spring,base package in XML-based configuration>> mandatory.
312+
313+
.Annotation-driven configuration of base packages
314+
====
315+
[source, java]
316+
----
317+
@EnableJpaRepositories(basePackages = "com.acme.repositories.jpa")
318+
@EnableMongoRepositories(basePackages = "com.acme.repositories.mongo")
319+
interface Configuration { }
320+
----
321+
====
322+
214323
[[repositories.query-methods.details]]
215324
== Defining query methods
216325

0 commit comments

Comments
 (0)