From 432269c5afac090d728a68b188bfa63f47f05beb Mon Sep 17 00:00:00 2001 From: Miykaelxxm Date: Thu, 3 Mar 2022 19:23:56 +0800 Subject: [PATCH] fix spring data format --- docs/en/spring-data/spring-data.md | 184 +++++++++++++---------------- 1 file changed, 85 insertions(+), 99 deletions(-) diff --git a/docs/en/spring-data/spring-data.md b/docs/en/spring-data/spring-data.md index 361c67d..8d83b69 100644 --- a/docs/en/spring-data/spring-data.md +++ b/docs/en/spring-data/spring-data.md @@ -1,10 +1,8 @@ -[](#preface)Preface -========== +# Preface The Spring Data Commons project applies core Spring concepts to the development of solutions using many relational and non-relational data stores. -[](#project)1. Project Metadata ----------- +## 1. Project Metadata * Version control: [https://github.com/spring-projects/spring-data-commons](https://github.com/spring-projects/spring-data-commons) @@ -16,11 +14,9 @@ The Spring Data Commons project applies core Spring concepts to the development * Snapshot repository: [https://repo.spring.io/libs-snapshot](https://repo.spring.io/libs-snapshot) -[](#reference-documentation)Reference Documentation -========== +## Reference Documentation -[](#dependencies)2. Dependencies ----------- +## 2. Dependencies Due to the different inception dates of individual Spring Data modules, most of them carry different major and minor version numbers. The easiest way to find compatible ones is to rely on the Spring Data Release Train BOM that we ship with the compatible versions defined. In a Maven project, you would declare this dependency in the `` section of your POM as follows: @@ -62,17 +58,16 @@ Example 2. Declaring a dependency to a Spring Data module ``` -### [](#dependencies.spring-boot)2.1. Dependency Management with Spring Boot ### +### 2.1. Dependency Management with Spring Boot Spring Boot selects a recent version of Spring Data modules for you. If you still want to upgrade to a newer version, set the `spring-data-releasetrain.version` property to the [train version and iteration](#dependencies.train-version) you would like to use. -### [](#dependencies.spring-framework)2.2. Spring Framework ### +### 2.2. Spring Framework The current version of Spring Data modules require Spring Framework 5.3.16 or better. The modules might also work with an older bugfix version of that minor version. However, using the most recent version within that generation is highly recommended. -[](#mapping.fundamentals)3. Object Mapping Fundamentals ----------- +## 3. Object Mapping Fundamentals This section covers the fundamentals of Spring Data object mapping, object creation, field and property access, mutability and immutability. Note, that this section only applies to Spring Data modules that do not use the object mapping of the underlying data store (like JPA). @@ -85,7 +80,7 @@ This means we need two fundamental steps: 2. Instance population to materialize all exposed properties. -### [](#mapping.object-creation)3.1. Object creation ### +### 3.1. Object creation Spring Data automatically tries to detect a persistent entity’s constructor to be used to materialize objects of that type. The resolution algorithm works as follows: @@ -138,7 +133,7 @@ For the domain class to be eligible for such optimization, it needs to adhere to If any of these criteria match, Spring Data will fall back to entity instantiation via reflection. -### [](#mapping.property-population)3.2. Property population ### +### 3.2. Property population Once an instance of the entity has been created, Spring Data populates all remaining persistent properties of that class. Unless already populated by the entity’s constructor (i.e. consumed through its constructor argument list), the identifier property will be populated first to allow the resolution of cyclic object references. @@ -275,7 +270,7 @@ class Person { |**5**| The `remarks` properties are mutable and populated by setting the `comment` field directly or by invoking the setter method for | |**6**| The class exposes a factory method and a constructor for object creation.
The core idea here is to use factory methods instead of additional constructors to avoid the need for constructor disambiguation through `@PersistenceConstructor`.
Instead, defaulting of properties is handled within the factory method. | -### [](#mapping.general-recommendations)3.3. General recommendations ### +### 3.3. General recommendations * *Try to stick to immutable objects* — Immutable objects are straightforward to create as materializing an object is then a matter of calling its constructor only. Also, this avoids your domain objects to be littered with setter methods that allow client code to manipulate the objects state. @@ -293,7 +288,7 @@ class Person { * *Use Lombok to avoid boilerplate code* — As persistence operations usually require a constructor taking all arguments, their declaration becomes a tedious repetition of boilerplate parameter to field assignments that can best be avoided by using Lombok’s `@AllArgsConstructor`. -#### [](#mapping.general-recommendations.override.properties)3.3.1. Overriding Properties #### +#### 3.3.1. Overriding Properties Java’s allows a flexible design of domain classes where a subclass could define a property that is already declared with the same name in its superclass. Consider the following example: @@ -358,7 +353,7 @@ From a programming model perspective there are a few things to consider: 3. Using `@AccessType(PROPERTY)` cannot be used as the super-property cannot be generally set without making any further assumptions of the setter implementation. -### [](#mapping.kotlin)3.4. Kotlin support ### +### 3.4. Kotlin support Spring Data adapts specifics of Kotlin to allow object creation and mutation. @@ -402,7 +397,7 @@ data class Person(val id: String, val name: String) This class is effectively immutable. It allows creating new instances as Kotlin generates a `copy(…)` method that creates new object instances copying all property values from the existing object and applying property values provided as arguments to the method. -#### [](#mapping.kotlin.override.properties)3.4.3. Kotlin Overriding Properties #### +#### 3.4.3. Kotlin Overriding Properties Kotlin allows declaring [property overrides](https://kotlinlang.org/docs/inheritance.html#overriding-properties) to alter properties in subclasses. @@ -472,15 +467,14 @@ From a programming model perspective there are a few things to consider: 3. Using `@AccessType(PROPERTY)` cannot be used as the super-property cannot be set. -[](#repositories)4. Working with Spring Data Repositories ----------- +## 4. Working with Spring Data Repositories The goal of the Spring Data repository abstraction is to significantly reduce the amount of boilerplate code required to implement data access layers for various persistence stores. | |*Spring Data repository documentation and your module*

This chapter explains the core concepts and interfaces of Spring Data repositories.
The information in this chapter is pulled from the Spring Data Commons module.
It uses the configuration and code samples for the Java Persistence API (JPA) module.
You should adapt the XML namespace declaration and the types to be extended to the equivalents of the particular module that you use. “[Namespace reference](#repositories.namespace-reference)” covers XML configuration, which is supported across all Spring Data modules that support the repository API. “[Repository query keywords](#repository-query-keywords)” covers the query method keywords supported by the repository abstraction in general.
For detailed information on the specific features of your module, see the chapter on that module of this document.| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#repositories.core-concepts)4.1. Core concepts ### +### 4.1. Core concepts The central interface in the Spring Data repository abstraction is `Repository`. It takes the domain class to manage as well as the ID type of the domain class as type arguments. @@ -564,7 +558,7 @@ interface UserRepository extends CrudRepository { } ``` -### [](#repositories.query-methods)4.2. Query Methods ### +### 4.2. Query Methods Standard CRUD functionality repositories usually have queries on the underlying datastore. With Spring Data, declaring those queries becomes a four-step process: @@ -645,13 +639,13 @@ The sections that follow explain each step in detail: * [Custom Implementations for Spring Data Repositories](#repositories.custom-implementations) -### [](#repositories.definition)4.3. Defining Repository Interfaces ### +### 4.3. Defining Repository Interfaces To define a repository interface, you first need to define a domain class-specific repository interface. The interface must extend `Repository` and be typed to the domain class and an ID type. If you want to expose CRUD methods for that domain type, extend `CrudRepository` instead of `Repository`. -#### [](#repositories.definition-tuning)4.3.1. Fine-tuning Repository Definition #### +#### 4.3.1. Fine-tuning Repository Definition Typically, your repository interface extends `Repository`, `CrudRepository`, or `PagingAndSortingRepository`. Alternatively, if you do not want to extend Spring Data interfaces, you can also annotate your repository interface with `@RepositoryDefinition`. @@ -685,7 +679,7 @@ So the `UserRepository` can now save users, find individual users by ID, and tri | |The intermediate repository interface is annotated with `@NoRepositoryBean`.
Make sure you add that annotation to all repository interfaces for which Spring Data should not create instances at runtime.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#repositories.multiple-modules)4.3.2. Using Repositories with Multiple Spring Data Modules #### +#### 4.3.2. Using Repositories with Multiple Spring Data Modules Using a unique Spring Data module in your application makes things simple, because all repository interfaces in the defined scope are bound to the Spring Data module. Sometimes, applications require using more than one Spring Data module. @@ -786,7 +780,7 @@ Example 14. Annotation-driven configuration of base packages class Configuration { … } ``` -### [](#repositories.query-methods.details)4.4. Defining Query Methods ### +### 4.4. Defining Query Methods The repository proxy has two ways to derive a store-specific query from the method name: @@ -798,7 +792,7 @@ Available options depend on the actual store. However, there must be a strategy that decides what actual query is created. The next section describes the available options. -#### [](#repositories.query-methods.query-lookup-strategies)4.4.1. Query Lookup Strategies #### +#### 4.4.1. Query Lookup Strategies The following strategies are available for the repository infrastructure to resolve the query. With XML configuration, you can configure the strategy at the namespace through the `query-lookup-strategy` attribute. @@ -819,7 +813,7 @@ Some strategies may not be supported for particular datastores. This is the default lookup strategy and, thus, is used if you do not configure anything explicitly. It allows quick query definition by method names but also custom-tuning of these queries by introducing declared queries as needed. -#### [](#repositories.query-methods.query-creation)4.4.2. Query Creation #### +#### 4.4.2. Query Creation The query builder mechanism built into the Spring Data repository infrastructure is useful for building constraining queries over entities of the repository. @@ -870,7 +864,7 @@ However, there are some general things to notice: * 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 “[Special parameter handling](#repositories.special-parameters)”. -#### [](#repositories.query-methods.query-property-expressions)4.4.3. Property Expressions #### +#### 4.4.3. Property Expressions Property expressions can refer only to a direct property of the managed entity, as shown in the preceding example. At query creation time, you already make sure that the parsed property is a property of the managed domain class. @@ -902,7 +896,7 @@ List findByAddress_ZipCode(ZipCode zipCode); Because we treat the underscore character as a reserved character, we strongly advise following standard Java naming conventions (that is, not using underscores in property names but using camel case instead). -#### [](#repositories.special-parameters)4.4.4. Special parameter handling #### +#### 4.4.4. Special parameter handling To handle parameters in your query, define method parameters as already seen in the preceding examples. Besides that, the infrastructure recognizes certain specific types like `Pageable` and `Sort`, to apply pagination and sorting to your queries dynamically. @@ -938,7 +932,7 @@ Rather, it restricts the query to look up only the given range of entities. | |To find out how many pages you get for an entire query, you have to trigger an additional count query.
By default, this query is derived from the query you actually trigger.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#repositories.paging-and-sorting)Paging and Sorting ##### +##### Paging and Sorting You can define simple sorting expressions by using property names. You can concatenate expressions to collect multiple criteria into one expression. @@ -973,7 +967,7 @@ QSort sort = QSort.by(QPerson.firstname.asc()) .and(QSort.by(QPerson.lastname.desc())); ``` -#### [](#repositories.limit-query-result)4.4.5. Limiting Query Results #### +#### 4.4.5. Limiting Query Results You can limit the results of query methods by using the `first` or `top` keywords, which you can use interchangeably. You can append an optional numeric value to `top` or `first` to specify the maximum result size to be returned. @@ -1004,13 +998,13 @@ If pagination or slicing is applied to a limiting query pagination (and the calc | |Limiting the results in combination with dynamic sorting by using a `Sort` parameter lets you express query methods for the 'K' smallest as well as for the 'K' biggest elements.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#repositories.collections-and-iterables)4.4.6. Repository Methods Returning Collections or Iterables #### +#### 4.4.6. Repository Methods Returning Collections or Iterables Query methods that return multiple results can use standard Java `Iterable`, `List`, and `Set`. Beyond that, we support returning Spring Data’s `Streamable`, a custom extension of `Iterable`, as well as collection types provided by [Vavr](https://www.vavr.io/). Refer to the appendix explaining all possible [query method return types](#appendix.query.return.types). -##### [](#repositories.collections-and-iterables.streamable)Using Streamable as Query Method Return Type ##### +##### Using Streamable as Query Method Return Type You can use `Streamable` as alternative to `Iterable` or any collection type. It provides convenience methods to access a non-parallel `Stream` (missing from `Iterable`) and the ability to directly `….filter(…)` and `….map(…)` over the elements and concatenate the `Streamable` to others: @@ -1027,7 +1021,7 @@ Streamable result = repository.findByFirstnameContaining("av") .and(repository.findByLastnameContaining("ea")); ``` -##### [](#repositories.collections-and-iterables.streamable-wrapper)Returning Custom Streamable Wrapper Types ##### +##### Returning Custom Streamable Wrapper Types Providing dedicated wrapper types for collections is a commonly used pattern to provide an API for a query result that returns multiple elements. Usually, these types are used by invoking a repository method returning a collection-like type and creating an instance of the wrapper type manually. @@ -1073,7 +1067,7 @@ interface ProductRepository implements Repository { |**4**| Implement the `Streamable` interface and delegate to the actual result. | |**5**| That wrapper type `Products` can be used directly as a query method return type.
You do not need to return `Streamable` and manually wrap it after the query in the repository client. | -##### [](#repositories.collections-and-iterables.vavr)Support for Vavr Collections ##### +##### Support for Vavr Collections [Vavr](https://www.vavr.io/) is a library that embraces functional programming concepts in Java. It ships with a custom set of collection types that you can use as query method return types, as the following table shows: @@ -1088,7 +1082,7 @@ You can use the types in the first column (or subtypes thereof) as query method Alternatively, you can declare `Traversable` (the Vavr `Iterable` equivalent), and we then derive the implementation class from the actual return value. That is, a `java.util.List` is turned into a Vavr `List` or `Seq`, a `java.util.Set` becomes a Vavr `LinkedHashSet` `Set`, and so on. -#### [](#repositories.nullability)4.4.7. Null Handling of Repository Methods #### +#### 4.4.7. Null Handling of Repository Methods As of Spring Data 2.0, repository CRUD methods that return an individual aggregate instance use Java 8’s `Optional` to indicate the potential absence of a value. Besides that, Spring Data supports returning the following wrapper types on query methods: @@ -1104,7 +1098,7 @@ The absence of a query result is then indicated by returning `null`. Repository methods returning collections, collection alternatives, wrappers, and streams are guaranteed never to return `null` but rather the corresponding empty representation. See “[Repository query return types](#repository-query-return-types)” for details. -##### [](#repositories.nullability.annotations)Nullability Annotations ##### +##### Nullability Annotations You can express nullability constraints for repository methods by using [Spring Framework’s nullability annotations](https://docs.spring.io/spring-framework/docs/5.3.16/reference/html/core.html#null-safety). They provide a tooling-friendly approach and opt-in `null` checks during runtime, as follows: @@ -1158,7 +1152,7 @@ interface UserRepository extends Repository { |**3**| Returns `null` when the query does not produce a result.
Also accepts `null` as the value for `emailAddress`. | |**4**| Returns `Optional.empty()` when the query does not produce a result.
Throws an `IllegalArgumentException` when the `emailAddress` handed to the method is `null`. | -##### [](#repositories.nullability.kotlin)Nullability in Kotlin-based Repositories ##### +##### Nullability in Kotlin-based Repositories Kotlin has the definition of [nullability constraints](https://kotlinlang.org/docs/reference/null-safety.html) baked into the language. Kotlin code compiles to bytecode, which does not express nullability constraints through method signatures but rather through compiled-in metadata. @@ -1180,7 +1174,7 @@ interface UserRepository : Repository { |-----|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |**2**| This method accepts `null` for the `firstname` parameter and returns `null` if the query does not produce a result. | -#### [](#repositories.query-streaming)4.4.8. Streaming Query Results #### +#### 4.4.8. Streaming Query Results You can process the results of query methods incrementally by using a Java 8 `Stream` as the return type. Instead of wrapping the query results in a `Stream`, data store-specific methods are used to perform the streaming, as shown in the following example: @@ -1211,7 +1205,7 @@ try (Stream stream = repository.findAllByCustomQueryAndStream()) { | |Not all Spring Data modules currently support `Stream` as a return type.| |---|---------------------------------------------------------------------------| -#### [](#repositories.query-async)4.4.9. Asynchronous Query Results #### +#### 4.4.9. Asynchronous Query Results You can run repository queries asynchronously by using [Spring’s asynchronous method running capability](https://docs.spring.io/spring-framework/docs/5.3.16/reference/html/integration.html#scheduling). This means the method returns immediately upon invocation while the actual query occurs in a task that has been submitted to a Spring `TaskExecutor`. @@ -1235,11 +1229,11 @@ ListenableFuture findOneByLastname(String lastname); (3) |**2**| Use a Java 8 `java.util.concurrent.CompletableFuture` as the return type. | |**3**|Use a `org.springframework.util.concurrent.ListenableFuture` as the return type.| -### [](#repositories.create-instances)4.5. Creating Repository Instances ### +### 4.5. Creating Repository Instances This section covers how to create instances and bean definitions for the defined repository interfaces. One way to do so is by using the Spring namespace that is shipped with each Spring Data module that supports the repository mechanism, although we generally recommend using Java configuration. -#### [](#repositories.create-instances.spring)4.5.1. XML Configuration #### +#### 4.5.1. XML Configuration Each Spring Data module includes a `repositories` element that lets you define a base package that Spring scans for you, as shown in the following example: @@ -1266,7 +1260,7 @@ Each bean is registered under a bean name that is derived from the interface nam Bean names for nested repository interfaces are prefixed with their enclosing type name. The `base-package` attribute allows wildcards so that you can define a pattern of scanned packages. -##### [](#repositories.using-filters)Using Filters ##### +##### Using Filters By default, the infrastructure picks up every interface that extends the persistence technology-specific `Repository` sub-interface located under the configured base package and creates a bean instance for it. However, you might want more fine-grained control over which interfaces have bean instances created for them. @@ -1286,7 +1280,7 @@ Example 28. Using exclude-filter element The preceding example excludes all interfaces ending in `SomeRepository` from being instantiated. -#### [](#repositories.create-instances.java-config)4.5.2. Java Configuration #### +#### 4.5.2. Java Configuration You can also trigger the repository infrastructure by using a store-specific `@Enable${store}Repositories` annotation on a Java configuration class. For an introduction to Java-based configuration of the Spring container, see [JavaConfig in the Spring reference documentation](https://docs.spring.io/spring-framework/docs/5.3.16/reference/html/core.html#beans-java). @@ -1309,7 +1303,7 @@ class ApplicationConfiguration { | |The preceding example uses the JPA-specific annotation, which you would change according to the store module you actually use. The same applies to the definition of the `EntityManagerFactory` bean. See the sections covering the store-specific configuration.| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#repositories.create-instances.standalone)4.5.3. Standalone Usage #### +#### 4.5.3. Standalone Usage You can also use the repository infrastructure outside of a Spring container — for example, in CDI environments. You still need some Spring libraries in your classpath, but, generally, you can set up repositories programmatically as well. The Spring Data modules that provide repository support ship with a persistence technology-specific `RepositoryFactory` that you can use, as follows: @@ -1320,13 +1314,13 @@ RepositoryFactorySupport factory = … // Instantiate factory here UserRepository repository = factory.getRepository(UserRepository.class); ``` -### [](#repositories.custom-implementations)4.6. Custom Implementations for Spring Data Repositories ### +### 4.6. Custom Implementations for Spring Data Repositories Spring Data provides various options to create query methods with little coding. But when those options don’t fit your needs you can also provide your own custom implementation for repository methods. This section describes how to do that. -#### [](#repositories.single-repository-behavior)4.6.1. Customizing Individual Repositories #### +#### 4.6.1. Customizing Individual Repositories To enrich a repository with custom functionality, you must first define a fragment interface and an implementation for the custom functionality, as follows: @@ -1446,7 +1440,7 @@ interface PersonRepository extends CrudRepository, CustomizedSave< } ``` -##### [](#repositories.configuration)Configuration ##### +##### Configuration If you use namespace configuration, the repository infrastructure tries to autodetect custom implementation fragments by scanning for classes below the package in which it found a repository. These classes need to follow the naming convention of appending the namespace element’s `repository-impl-postfix` attribute to the fragment interface name. @@ -1464,7 +1458,7 @@ Example 38. Configuration example The first configuration in the preceding example tries to look up a class called `com.acme.repository.CustomizedUserRepositoryImpl` to act as a custom repository implementation. The second example tries to look up `com.acme.repository.CustomizedUserRepositoryMyPostfix`. -###### [](#repositories.single-repository-behaviour.ambiguity)Resolution of Ambiguity ###### +###### Resolution of Ambiguity If multiple implementations with matching class names are found in different packages, Spring Data uses the bean names to identify which one to use. @@ -1494,7 +1488,7 @@ class CustomizedUserRepositoryImpl implements CustomizedUserRepository { If you annotate the `UserRepository` interface with `@Component("specialCustom")`, the bean name plus `Impl` then matches the one defined for the repository implementation in `com.acme.impl.two`, and it is used instead of the first one. -###### [](#repositories.manual-wiring)Manual Wiring ###### +###### Manual Wiring If your custom implementation uses annotation-based configuration and autowiring only, the preceding approach shown works well, because it is treated as any other Spring bean. If your implementation fragment bean needs special wiring, you can declare the bean and name it according to the conventions described in the [preceding section](#repositories.single-repository-behaviour.ambiguity). @@ -1511,7 +1505,7 @@ Example 40. Manual wiring of custom implementations ``` -#### [](#repositories.customize-base-repository)4.6.2. Customize the Base Repository #### +#### 4.6.2. Customize the Base Repository The approach described in the [preceding section](#repositories.manual-wiring) requires customization of each repository interfaces when you want to customize the base repository behavior so that all repositories are affected. To instead change behavior for all repositories, you can create an implementation that extends the persistence technology-specific repository base class. @@ -1563,7 +1557,7 @@ Example 43. Configuring a custom repository base class using XML base-class="….MyRepositoryImpl" /> ``` -### [](#core.domain-events)4.7. Publishing Events from Aggregate Roots ### +### 4.7. Publishing Events from Aggregate Roots Entities managed by repositories are aggregate roots. In a Domain-Driven Design application, these aggregate roots usually publish domain events. @@ -1592,12 +1586,12 @@ class AnAggregateRoot { The methods are called every time one of a Spring Data repository’s `save(…)`, `saveAll(…)`, `delete(…)` or `deleteAll(…)` methods are called. -### [](#core.extensions)4.8. Spring Data Extensions ### +### 4.8. Spring Data Extensions This section documents a set of Spring Data extensions that enable Spring Data usage in a variety of contexts. Currently, most of the integration is targeted towards Spring MVC. -#### [](#core.extensions.querydsl)4.8.1. Querydsl Extension #### +#### 4.8.1. Querydsl Extension [Querydsl](http://www.querydsl.com/) is a framework that enables the construction of statically typed SQL-like queries through its fluent API. @@ -1644,7 +1638,7 @@ Predicate predicate = user.firstname.equalsIgnoreCase("dave") userRepository.findAll(predicate); ``` -#### [](#core.web)4.8.2. Web support #### +#### 4.8.2. Web support Spring Data modules that support the repository programming model ship with a variety of web support. The web related components require Spring MVC JARs to be on the classpath. @@ -1675,7 +1669,7 @@ Example 48. Enabling Spring Data web support in XML ``` -##### [](#core.web.basic)Basic Web Support ##### +##### Basic Web Support The configuration shown in the [previous section](#core.web) registers a few basic components: @@ -1685,7 +1679,7 @@ The configuration shown in the [previous section](#core.web) registers a few bas * [Jackson Modules](#core.web.basic.jackson-mappers) to de-/serialize types like `Point` and `Distance`, or store specific ones, depending on the Spring Data Module used. -###### [](#core.web.basic.domain-class-converter)Using the `DomainClassConverter` Class ###### +###### Using the `DomainClassConverter` Class The `DomainClassConverter` class lets you use domain types in your Spring MVC controller method signatures directly so that you need not manually lookup the instances through the repository, as the following example shows: @@ -1711,7 +1705,7 @@ The instance can be resolved by letting Spring MVC convert the path variable int | |Currently, the repository has to implement `CrudRepository` to be eligible to be discovered for conversion.| |---|-----------------------------------------------------------------------------------------------------------| -###### [](#core.web.basic.paging-and-sorting)HandlerMethodArgumentResolvers for Pageable and Sort ###### +###### HandlerMethodArgumentResolvers for Pageable and Sort The configuration snippet shown in the [previous section](#core.web.basic.domain-class-converter) also registers a `PageableHandlerMethodArgumentResolver` as well as an instance of `SortHandlerMethodArgumentResolver`. The registration enables `Pageable` and `Sort` as valid controller method arguments, as the following example shows: @@ -1770,7 +1764,7 @@ You have to populate `thing1_page`, `thing2_page`, and so on. The default `Pageable` passed into the method is equivalent to a `PageRequest.of(0, 20)`, but you can customize it by using the `@PageableDefault` annotation on the `Pageable` parameter. -##### [](#core.web.pageables)Hypermedia Support for Pageables ##### +##### Hypermedia Support for Pageables Spring HATEOAS ships with a representation model class (`PagedResources`) that allows enriching the content of a `Page` instance with the necessary `Page` metadata as well as links to let the clients easily navigate the pages. The conversion of a `Page` to a `PagedResources` is done by an implementation of the Spring HATEOAS `ResourceAssembler` interface, called the `PagedResourcesAssembler`. @@ -1828,7 +1822,7 @@ The assembler produced the correct URI and also picked up the default configurat This means that, if you change that configuration, the links automatically adhere to the change. By default, the assembler points to the controller method it was invoked in, but you can customize that by passing a custom `Link` to be used as base to build the pagination links, which overloads the `PagedResourcesAssembler.toResource(…)` method. -##### [](#core.web.basic.jackson-mappers)Spring Data Jackson Modules ##### +##### Spring Data Jackson Modules The core module, and some of the store specific ones, ship with a set of Jackson Modules for types, like `org.springframework.data.geo.Distance` and `org.springframework.data.geo.Point`, used by the Spring Data domain. Those Modules are imported once [web support](#core.web) is enabled and `com.fasterxml.jackson.databind.ObjectMapper` is available. @@ -1848,7 +1842,7 @@ org.springframework.data.geo.Polygon | |The individual module may provide additional `SpringDataJacksonModules`.
Please refer to the store specific section for more details.| |---|-------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#core.web.binding)Web Databinding Support ##### +##### Web Databinding Support You can use Spring Data projections (described in [Projections](#projections)) to bind incoming request payloads by using either [JSONPath](https://goessner.net/articles/JsonPath/) expressions (requires [Jayway JsonPath](https://github.com/json-path/JsonPath) or [XPath](https://www.w3.org/TR/xpath-31/) expressions (requires [XmlBeam](https://xmlbeam.org/)), as the following example shows: @@ -1882,7 +1876,7 @@ For usage with `RestTemplate`, register a `ProjectingJackson2HttpMessageConverte For more information, see the [web projection example](https://github.com/spring-projects/spring-data-examples/tree/master/web/projection) in the canonical [Spring Data Examples repository](https://github.com/spring-projects/spring-data-examples). -##### [](#core.web.type-safe)Querydsl Web Support ##### +##### Querydsl Web Support For those stores that have [QueryDSL](http://www.querydsl.com/) integration, you can derive queries from the attributes contained in a `Request` query string. @@ -1964,7 +1958,7 @@ interface UserRepository extends CrudRepository, | |You can register a `QuerydslBinderCustomizerDefaults` bean holding default Querydsl bindings before applying specific bindings from the repository or `@QuerydslPredicate`.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#core.repository-populators)4.8.3. Repository Populators #### +#### 4.8.3. Repository Populators If you work with the Spring JDBC module, you are probably familiar with the support for populating a `DataSource` with SQL scripts. A similar abstraction is available on the repositories level, although it does not use SQL as the data definition language because it must be store-independent. @@ -2035,8 +2029,7 @@ Example 55. Declaring an unmarshalling repository populator (using JAXB) ``` -[](#projections)5. Projections ----------- +## 5. Projections Spring Data query methods usually return one or multiple instances of the aggregate root managed by the repository. However, it might sometimes be desirable to create projections based on certain attributes of those types. @@ -2067,7 +2060,7 @@ interface PersonRepository extends Repository { Now imagine that we want to retrieve the person’s name attributes only. What means does Spring Data offer to achieve this? The rest of this chapter answers that question. -### [](#projections.interfaces)5.1. Interface-based Projections ### +### 5.1. Interface-based Projections The easiest way to limit the result of the queries to only the name attributes is by declaring an interface that exposes accessor methods for the properties to be read, as shown in the following example: @@ -2117,7 +2110,7 @@ interface PersonSummary { On method invocation, the `address` property of the target instance is obtained and wrapped into a projecting proxy in turn. -#### [](#projections.interfaces.closed)5.1.1. Closed Projections #### +#### 5.1.1. Closed Projections A projection interface whose accessor methods all match properties of the target aggregate is considered to be a closed projection. The following example (which we used earlier in this chapter, too) is a closed projection: @@ -2134,7 +2127,7 @@ interface NamesOnly { If you use a closed projection, Spring Data can optimize the query execution, because we know about all the attributes that are needed to back the projection proxy. For more details on that, see the module-specific part of the reference documentation. -#### [](#projections.interfaces.open)5.1.2. Open Projections #### +#### 5.1.2. Open Projections Accessor methods in projection interfaces can also be used to compute new values by using the `@Value` annotation, as shown in the following example: @@ -2208,7 +2201,7 @@ interface NamesOnly { Again, for more complex expressions, you should use a Spring bean and let the expression invoke a method, as described [earlier](#projections.interfaces.open.bean-reference). -#### [](#projections.interfaces.nullable-wrappers)5.1.3. Nullable Wrappers #### +#### 5.1.3. Nullable Wrappers Getters in projection interfaces can make use of nullable wrappers for improved null-safety. Currently supported wrapper types are: @@ -2232,7 +2225,7 @@ interface NamesOnly { If the underlying projection value is not `null`, then values are returned using the present-representation of the wrapper type. In case the backing value is `null`, then the getter method returns the empty representation of the used wrapper type. -### [](#projections.dtos)5.2. Class-based Projections (DTOs) ### +### 5.2. Class-based Projections (DTOs) Another way of defining projections is by using value type DTOs (Data Transfer Objects) that hold properties for the fields that are supposed to be retrieved. These DTO types can be used in exactly the same way projection interfaces are used, except that no proxying happens and no nested projections can be applied. @@ -2269,7 +2262,7 @@ class NamesOnly { | |Avoid boilerplate code for projection DTOs

You can dramatically simplify the code for a DTO by using [Project Lombok](https://projectlombok.org), which provides an `@Value` annotation (not to be confused with Spring’s `@Value` annotation shown in the earlier interface examples).
If you use Project Lombok’s `@Value` annotation, the sample DTO shown earlier would become the following:

```
@Value
class NamesOnly {
String firstname, lastname;
}
```

Fields are `private final` by default, and the class exposes a constructor that takes all fields and automatically gets `equals(…)` and `hashCode()` methods implemented.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#projection.dynamic)5.3. Dynamic Projections ### +### 5.3. Dynamic Projections So far, we have used the projection type as the return type or element type of a collection. However, you might want to select the type to be used at invocation time (which makes it dynamic). @@ -2302,10 +2295,9 @@ void someMethod(PersonRepository people) { | |Query parameters of type `Class` are inspected whether they qualify as dynamic projection parameter.
If the actual return type of the query equals the generic parameter type of the `Class` parameter, then the matching `Class` parameter is not available for usage within the query or SpEL expressions.
If you want to use a `Class` parameter as query argument then make sure to use a different generic parameter, for example `Class`.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -[](#query-by-example)6. Query by Example ----------- +## 6. Query by Example -### [](#query-by-example.introduction)6.1. Introduction ### +### 6.1. Introduction This chapter provides an introduction to Query by Example and explains how to use it. @@ -2313,7 +2305,7 @@ Query by Example (QBE) is a user-friendly querying technique with a simple inter It allows dynamic query creation and does not require you to write queries that contain field names. In fact, Query by Example does not require you to write queries by using store-specific query languages at all. -### [](#query-by-example.usage)6.2. Usage ### +### 6.2. Usage The Query by Example API consists of three parts: @@ -2398,7 +2390,7 @@ public interface QueryByExampleExecutor { } ``` -### [](#query-by-example.matchers)6.3. Example Matchers ### +### 6.3. Example Matchers Examples are not limited to default settings. You can specify your own defaults for string matching, null handling, and property-specific settings by using the `ExampleMatcher`, as shown in the following example: @@ -2469,10 +2461,9 @@ The following table describes the scope of the various `ExampleMatcher` settings | Case sensitivity |`ExampleMatcher` and property path| |Value transformation| Property path | -[](#auditing)7. Auditing ----------- +## 7. Auditing -### [](#auditing.basics)7.1. Basics ### +### 7.1. Basics Spring Data provides sophisticated support to transparently keep track of who created or changed an entity and when the change happened. To benefit from that functionality, you have to equip your entity classes with auditing metadata that can be defined either using annotations or by implementing an interface. Additionally, auditing has to be enabled either through Annotation configuration or XML configuration to register the required infrastructure components. @@ -2481,7 +2472,7 @@ Please refer to the store-specific section for configuration samples. | |Applications that only track creation and modification dates do not need to specify an [`AuditorAware`](#auditing.auditor-aware).| |---|---------------------------------------------------------------------------------------------------------------------------------| -#### [](#auditing.annotations)7.1.1. Annotation-based Auditing Metadata #### +#### 7.1.1. Annotation-based Auditing Metadata We provide `@CreatedBy` and `@LastModifiedBy` to capture the user who created or modified the entity as well as `@CreatedDate` and `@LastModifiedDate` to capture when the change happened. @@ -2525,11 +2516,11 @@ class AuditMetadata { } ``` -#### [](#auditing.interfaces)7.1.2. Interface-based Auditing Metadata #### +#### 7.1.2. Interface-based Auditing Metadata In case you do not want to use annotations to define auditing metadata, you can let your domain class implement the `Auditable` interface. It exposes setter methods for all of the auditing properties. -#### [](#auditing.auditor-aware)7.1.3. `AuditorAware` #### +#### 7.1.3. `AuditorAware` In case you use either `@CreatedBy` or `@LastModifiedBy`, the auditing infrastructure somehow needs to become aware of the current principal. To do so, we provide an `AuditorAware` SPI interface that you have to implement to tell the infrastructure who the current user or system interacting with the application is. The generic type `T` defines what type the properties annotated with `@CreatedBy` or `@LastModifiedBy` have to be. @@ -2554,7 +2545,7 @@ class SpringSecurityAuditorAware implements AuditorAware { The implementation accesses the `Authentication` object provided by Spring Security and looks up the custom `UserDetails` instance that you have created in your `UserDetailsService` implementation. We assume here that you are exposing the domain user through the `UserDetails` implementation but that, based on the `Authentication` found, you could also look it up from anywhere. -#### [](#auditing.reactive-auditor-aware)7.1.4. `ReactiveAuditorAware` #### +#### 7.1.4. `ReactiveAuditorAware` When using reactive infrastructure you might want to make use of contextual information to provide `@CreatedBy` or `@LastModifiedBy` information. We provide an `ReactiveAuditorAware` SPI interface that you have to implement to tell the infrastructure who the current user or system interacting with the application is. The generic type `T` defines what type the properties annotated with `@CreatedBy` or `@LastModifiedBy` have to be. @@ -2580,13 +2571,11 @@ class SpringSecurityAuditorAware implements ReactiveAuditorAware { The implementation accesses the `Authentication` object provided by Spring Security and looks up the custom `UserDetails` instance that you have created in your `UserDetailsService` implementation. We assume here that you are exposing the domain user through the `UserDetails` implementation but that, based on the `Authentication` found, you could also look it up from anywhere. -[](#appendix)Appendices -========== +## Appendices -[](#repositories.namespace-reference)Appendix A: Namespace reference ----------- +## Appendix A: Namespace reference -### [](#populator.namespace-dao-config)The `` Element ### +### The `` Element The `` element triggers the setup of the Spring Data repository infrastructure. The most important attribute is `base-package`, which defines the package to scan for Spring Data repository interfaces. See “[XML Configuration](#repositories.create-instances.spring)”. The following table describes the attributes of the `` element: @@ -2598,10 +2587,9 @@ The `` element triggers the setup of the Spring Data repository | `named-queries-location` | Defines the location to search for a Properties file containing externally defined queries. | |`consider-nested-repositories`| Whether nested repository interface definitions should be considered. Defaults to `false`. | -[](#populator.namespace-reference)Appendix B: Populators namespace reference ----------- +## Appendix B: Populators namespace reference -### [](#namespace-dao-config)The \ element ### +### The \ element The `` element allows to populate the a data store via the Spring Data repository infrastructure.[1] @@ -2609,10 +2597,9 @@ The `` element allows to populate the a data store via the Spring D |-----------|----------------------------------------------------------------------------------------| |`locations`|Where to find the files to read the objects from the repository shall be populated with.| -[](#repository-query-keywords)Appendix C: Repository query keywords ----------- +## Appendix C: Repository query keywords -### [](#appendix.query.method.subject)Supported query method subject keywords ### +### Supported query method subject keywords The following table lists the subject keywords generally supported by the Spring Data repository query derivation mechanism to express the predicate. Consult the store-specific documentation for the exact list of supported keywords, because some keywords listed here might not be supported in a particular store. @@ -2626,7 +2613,7 @@ Consult the store-specific documentation for the exact list of supported keyword | `…First…`, `…Top…` | Limit the query results to the first `` of results. This keyword can occur in any place of the subject between `find` (and the other keywords) and `by`. | | `…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.predicate)Supported query method predicate keywords and modifiers ### +### Supported query method predicate keywords and modifiers The following table lists the predicate keywords generally supported by the Spring Data repository query derivation mechanism. However, consult the store-specific documentation for the exact list of supported keywords, because some keywords listed here might not be supported in a particular store. @@ -2670,10 +2657,9 @@ In addition to filter predicates, the following list of modifiers is supported: |`AllIgnoreCase`, `AllIgnoringCase`| Ignore case for all suitable properties. Used somewhere in the query method predicate. | | `OrderBy…` |Specify a static sorting order followed by the property path and direction (e. g. `OrderByFirstnameAscLastnameDesc`).| -[](#repository-query-return-types)Appendix D: Repository query return types ----------- +## Appendix D: Repository query return types -### [](#appendix.query.return.types)Supported Query Return Types ### +### Supported Query Return Types The following table lists the return types generally supported by Spring Data repositories. However, consult the store-specific documentation for the exact list of supported return types, because some types listed here might not be supported in a particular store. -- GitLab