Skip to content

Update documentation. #3174

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>3.4.0-SNAPSHOT</version>
<version>3.4.0-3173-SNAPSHOT</version>

<name>Spring Data Core</name>
<description>Core Spring concepts underpinning every Spring Data module.</description>
Expand Down
21 changes: 21 additions & 0 deletions src/main/antora/modules/ROOT/pages/repositories/core-concepts.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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".
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@odrotbohm any opinion on wording? We want to make the point that identifiers need sometimes a different handling than properties, yet in both cases we need to express access to these via some name.


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]]
Expand Down Expand Up @@ -37,6 +49,15 @@ public interface CrudRepository<T, ID> extends Repository<T, ID> {
The methods declared in this interface are commonly referred to as CRUD methods.
`ListCrudRepository` offers equivalent methods, but they return `List` where the `CrudRepository` methods return an `Iterable`.

[IMPORTANT]
====
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`.
Those interfaces extend `CrudRepository` and expose the capabilities of the underlying persistence technology in addition to the rather generic persistence technology-agnostic interfaces such as `CrudRepository`.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,22 @@ Consult the store-specific documentation for the exact list of supported keyword
|`…Distinct…`| Use a distinct query to return only unique results. Consult the store-specific documentation whether that feature is supported. This keyword can occur in any place of the subject between `find` (and the other keywords) and `by`.
|===============

[[appendix.query.method.reserved]]
== Reserved 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
|===============
|`deleteAllById(Iterable<ID> identifiers)`
|`deleteById(ID identifier)`
|`existsById(ID identifier)`
|`findAllById(Iterable<ID> identifiers)`
|`findById(ID identifier)`
|===============

[[appendix.query.method.predicate]]
== Supported query method predicate keywords and modifiers

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,47 @@ Whether ignoring cases is supported may vary by store, so consult the relevant s
- You can apply static ordering by appending an `OrderBy` clause to the query method that references a property and by providing a sorting direction (`Asc` or `Desc`).
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 Method Names

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]
----
class User {
@Id Long pk; <1>

Long id; <2>

// …
}

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 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.

[[repositories.query-methods.query-property-expressions]]
== Property Expressions

Expand Down