Polishing.
Add DDD context. Explain identifier to domain object relationship. Tweak wording. See #3173 Original pull request: #3174
This commit is contained in:
@@ -4,6 +4,18 @@
|
||||
The central interface in the Spring Data repository abstraction is `Repository`.
|
||||
It takes the domain class to manage as well as the identifier type of the domain class as type arguments.
|
||||
This interface acts primarily as a marker interface to capture the types to work with and to help you to discover interfaces that extend this one.
|
||||
|
||||
[TIP]
|
||||
====
|
||||
Spring Data considers domain types to be entities, more specifically aggregates.
|
||||
So you will see the term "entity" used throughout the documentation that can be interchanged with the term "domain type" or "aggregate".
|
||||
|
||||
As you might have noticed in the introduction it already hinted towards domain-driven concepts.
|
||||
We consider domain objects in the sense of DDD.
|
||||
Domain objects have identifiers (otherwise these would be identity-less value objects), and we somehow need to refer to identifiers when working with certain patterns to access data.
|
||||
Referring to identifiers will become more meaningful as we talk about repositories and query methods.
|
||||
====
|
||||
|
||||
The {spring-data-commons-javadoc-base}/org/springframework/data/repository/CrudRepository.html[`CrudRepository`] and {spring-data-commons-javadoc-base}/org/springframework/data/repository/ListCrudRepository.html[`ListCrudRepository`] interfaces provide sophisticated CRUD functionality for the entity class that is being managed.
|
||||
|
||||
[[repositories.repository]]
|
||||
@@ -39,7 +51,11 @@ The methods declared in this interface are commonly referred to as CRUD methods.
|
||||
|
||||
[IMPORTANT]
|
||||
====
|
||||
The repository interface implies a few reserved methods like `findById(ID identifier)` that always target the domain types identifier property regardless of its property name. Read more about this in "`xref:repositories/query-methods-details.adoc#repositories.query-methods.reserved-methods[Defining Query Methods]`".
|
||||
The repository interface implies a few reserved methods like `findById(ID identifier)` that target the domain type identifier property regardless of its property name.
|
||||
Read more about this in "`xref:repositories/query-methods-details.adoc#repositories.query-methods.reserved-methods[Defining Query Methods]`".
|
||||
|
||||
You can annotate your query method with `@Query` to provide a custom query if a property named `Id` doesn't refer to the identifier.
|
||||
Following that path can easily lead to confusion and is discouraged as you will quickly hit type limits if the `ID` type and the type of your `Id` property deviate.
|
||||
====
|
||||
|
||||
NOTE: We also provide persistence technology-specific abstractions, such as `JpaRepository` or `MongoRepository`.
|
||||
|
||||
@@ -24,7 +24,9 @@ Consult the store-specific documentation for the exact list of supported keyword
|
||||
[[appendix.query.method.reserved]]
|
||||
== Reserved methods
|
||||
|
||||
The following table lists reserved methods that use predefined functionality which is directly invoked on the backing (store specific) implementation of the repository proxy. See also "`xref:repositories/query-methods-details.adoc#repositories.query-methods.reserved-methods[Defining Query Methods]`".
|
||||
The following table lists reserved methods that use predefined functionality (as defined in `CrudRepository`).
|
||||
These methods are directly invoked on the backing (store-specific) implementation of the repository proxy.
|
||||
See also "`xref:repositories/query-methods-details.adoc#repositories.query-methods.reserved-methods[Defining Query Methods]`".
|
||||
|
||||
.Reserved methods
|
||||
|===============
|
||||
|
||||
@@ -87,35 +87,45 @@ Whether ignoring cases is supported may vary by store, so consult the relevant s
|
||||
To create a query method that supports dynamic sorting, see "`xref:repositories/query-methods-details.adoc#repositories.special-parameters[Paging, Iterating Large Results, Sorting & Limiting]`".
|
||||
|
||||
[[repositories.query-methods.reserved-methods]]
|
||||
== Reserved Methods
|
||||
== Reserved Method Names
|
||||
|
||||
While repository methods typically bind to properties by name, there are a few exceptions to this rule when it comes to certain method names targeting the _identifier_ property. Those _reserved methods_ like `CrudRepository#findById` or just `findById` are targeting the _identifier_ property independent of the actual property name used in the declared method. +
|
||||
Consider the following domain type holding a property `pk` marked as the identifier via `@Id` and a property called `id`. In this case you need to pay close attention to the naming of your lookup methods as they may collide with predefined signatures.
|
||||
While derived repository methods bind to properties by name, there are a few exceptions to this rule when it comes to certain method names inherited from the base repository targeting the _identifier_ property.
|
||||
Those _reserved methods_ like `CrudRepository#findById` (or just `findById`) are targeting the _identifier_ property regardless of the actual property name used in the declared method.
|
||||
|
||||
Consider the following domain type holding a property `pk` marked as the identifier via `@Id` and a property called `id`.
|
||||
In this case you need to pay close attention to the naming of your lookup methods as they may collide with predefined signatures:
|
||||
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
public class User {
|
||||
@Id
|
||||
Long pk; <1>
|
||||
Long id; <2>
|
||||
// ...
|
||||
class User {
|
||||
@Id Long pk; <1>
|
||||
|
||||
Long id; <2>
|
||||
|
||||
// …
|
||||
}
|
||||
|
||||
public interface UserRepository extends Repository<User, Long> {
|
||||
Optional<User> findById(Long id); <3>
|
||||
Optional<User> findByPk(Long pk); <4>
|
||||
interface UserRepository extends Repository<User, Long> {
|
||||
|
||||
Optional<User> findById(Long id); <3>
|
||||
|
||||
Optional<User> findByPk(Long pk); <4>
|
||||
|
||||
Optional<User> findUserById(Long id); <5>
|
||||
}
|
||||
----
|
||||
<1> The identifier property / primary key.
|
||||
<2> A property called id, but not the identifying one.
|
||||
<3> Targets the `User#pk` property (the one marked with `@Id` which is considered to be the identifier) instead of `User#id` as the property name would suggest because it is one of the _reserved methods_.
|
||||
<4> Targets the `User#pk` property by name.
|
||||
<5> Targets the `User#id` property by using the descriptive token between `find` and `by` to avoid collisions with _reserved methods_.
|
||||
|
||||
<1> The identifier property (primary key).
|
||||
<2> A property named `id`, but not the identifier.
|
||||
<3> Targets the `pk` property (the one marked with `@Id` which is considered to be the identifier) as it refers to a `CrudRepository` base repository method.
|
||||
Therefore, it is not a derived query using of `id` as the property name would suggest because it is one of the _reserved methods_.
|
||||
<4> Targets the `pk` property by name as it is a derived query.
|
||||
<5> Targets the `id` property by using the descriptive token between `find` and `by` to avoid collisions with _reserved methods_.
|
||||
====
|
||||
|
||||
This special behaviour not only targets lookup methods but also applies to the `exits` and `delete` ones. Please refer to the "`xref:repositories/query-keywords-reference.adoc#appendix.query.method.reserved[Repository query keywords]`" for the list of methods.
|
||||
This special behaviour not only targets lookup methods but also applies to the `exits` and `delete` ones.
|
||||
Please refer to the "`xref:repositories/query-keywords-reference.adoc#appendix.query.method.reserved[Repository query keywords]`" for the list of methods.
|
||||
|
||||
[[repositories.query-methods.query-property-expressions]]
|
||||
== Property Expressions
|
||||
|
||||
Reference in New Issue
Block a user