Skip to content

Commit ed7f52d

Browse files
Include AOT section from data commons.
See: spring-projects/spring-data-commons#3384
1 parent 7193e2f commit ed7f52d

File tree

1 file changed

+11
-180
lines changed
  • src/main/antora/modules/ROOT/pages/jpa

1 file changed

+11
-180
lines changed
Lines changed: 11 additions & 180 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,19 @@
1-
= Ahead of Time Optimizations
1+
include::{commons}@data-commons::page$aot.adoc[]
22

3-
This chapter covers Spring Data's Ahead of Time (AOT) optimizations that build upon {spring-framework-docs}/core/aot.html[Spring's Ahead of Time Optimizations].
3+
[[aot.repositories.jpa]]
4+
== JPA Ahead of Time Repositories
45

5-
[[aot.bestpractices]]
6-
== Best Practices
7-
8-
=== Annotate your Domain Types
9-
10-
During application startup, Spring scans the classpath for domain classes for early processing of entities.
11-
By annotating your domain types with Spring Data-specific `@Table`, `@Document` or `@Entity` annotations you can aid initial entity scanning and ensure that those types are registered with `ManagedTypes` for Runtime Hints.
12-
Classpath scanning is not possible in native image arrangements and so Spring has to use `ManagedTypes` for the initial entity set.
13-
14-
[[aot.hints]]
15-
== Runtime Hints
16-
17-
Running an application as a native image requires additional information compared to a regular JVM runtime.
18-
Spring Data contributes {spring-framework-docs}/core/aot.html#aot.hints[Runtime Hints] during AOT processing for native image usage.
19-
These are in particular hints for:
20-
21-
* Auditing
22-
* `ManagedTypes` to capture the outcome of class-path scans
23-
* Repositories
24-
** Reflection hints for entities, return types, and Spring Data annotations
25-
** Repository fragments
26-
** Querydsl `Q` classes
27-
** Kotlin Coroutine support
28-
* Web support (Jackson Hints for `PagedModel`)
29-
30-
[[aot.repositories]]
31-
== Ahead of Time Repositories
32-
33-
AOT Repositories are an extension to AOT processing by pre-generating eligible query method implementations.
34-
Query methods are opaque to developers regarding their underlying queries being executed in a query method call.
35-
AOT repositories contribute query method implementations based on derived, annotated, and named queries that are known at build-time.
36-
This optimization moves query method processing from runtime to build-time, which can lead to a significant performance improvement as query methods do not need to be analyzed reflectively upon each application start.
37-
38-
The resulting AOT repository fragment follows the naming scheme of `<Repository FQCN>Impl__Aot` and is placed in the same package as the repository interface.
39-
You can find all queries in their String form for generated repository query methods.
40-
41-
NOTE: Consider AOT repository classes an internal optimization.
42-
Do not use them directly in your code as generation and implementation details may change in future releases.
43-
44-
=== Running with AOT Repositories
45-
46-
AOT is a mandatory step to transform a Spring application to a native executable, so it is automatically enabled when running in this mode.
47-
When AOT is enabled (either for native compilation or by setting `spring.aot.enabled=true`), AOT repositories are automatically enabled by default.
48-
49-
You can disable AOT repository generation entirely or only disable JPA AOT repositories:
50-
51-
* Set the `spring.aot.repositories.enabled=false` property to disable generated repositories for all Spring Data modules.
52-
* Set the `spring.aot.jpa.repositories.enabled=false` property to disable only JPA AOT repositories.
53-
54-
AOT repositories contribute configuration changes to the actual repository bean registration to register the generated repository fragment.
55-
56-
NOTE: When AOT optimizations are included, some decisions that have been taken at build-time are hard-coded in the application setup.
57-
For instance, profiles that have been enabled at build-time are automatically enabled at runtime as well.
58-
Also, the Spring Data module implementing a repository is fixed.
59-
Changing the implementation requires AOT re-processing.
6+
AOT repositories filter methods that are eligible for AOT processing.
7+
These are typically all query methods that are not backed by an xref:repositories/custom-implementations.adoc[implementation fragment].
608

61-
NOTE: AOT processing avoids database access.
9+
[NOTE]
10+
====
11+
AOT processing avoids database access.
6212
Therefore, it initializes an in-memory Hibernate instance for metadata collection.
6313
Types for the Hibernate configuration are determined by our AOT metadata collector.
6414
We prefer using a `PersistentEntityTypes` bean if available and fall back to `PersistenceUnitInfo` or our own discovered types.
6515
If our type scanning is not sufficient for your arrangement, you can enable direct `EntityManagerFactory` usage by configuring the `spring.aot.jpa.repositories.use-entitymanager=true` property.
66-
67-
=== Eligible Methods
68-
69-
AOT repositories filter methods that are eligible for AOT processing.
70-
These are typically all query methods that are not backed by an xref:repositories/custom-implementations.adoc[implementation fragment].
16+
====
7117

7218
**Supported Features**
7319

@@ -85,127 +31,12 @@ Mind that using Value Expressions requires expression parsing and contextual inf
8531

8632
* Requires Hibernate for AOT processing.
8733
* `QueryRewriter` must be a no-args class. `QueryRewriter` beans are not yet supported.
88-
* Methods accepting `ScrollPosition` (e.g. `Keyset` pagination) are not yet supported
34+
* Methods accepting `ScrollPosition` (e.g. `Keyset` pagination) are not yet supported.
35+
* Custom Collection return types (e.g. `io.vavr.collection`, `"org.eclipse.collections`) are not yet supported.
8936

9037
**Excluded methods**
9138

9239
* `CrudRepository`, Querydsl, Query by Example, and other base interface methods as their implementation is provided by the base class respective fragments
9340
* Methods whose implementation would be overly complex
9441
** Methods accepting `ScrollPosition` (e.g. `Keyset` pagination)
9542
** Dynamic projections
96-
97-
[[aot.repositories.json]]
98-
== Repository Metadata
99-
100-
AOT processing introspects query methods and collects metadata about repository queries.
101-
Spring Data JPA stores this metadata in JSON files that are named like the repository interface and stored next to it (i.e. within the same package).
102-
Repository JSON Metadata contains details about queries and fragments.
103-
An example for the following repository is shown below:
104-
105-
====
106-
[source,java]
107-
----
108-
interface UserRepository extends CrudRepository<User, Integer> {
109-
110-
List<User> findUserNoArgumentsBy(); <1>
111-
112-
Page<User> findPageOfUsersByLastnameStartingWith(String lastname, Pageable page); <2>
113-
114-
@Query("select u from User u where u.emailAddress = ?1")
115-
User findAnnotatedQueryByEmailAddress(String emailAddress); <3>
116-
117-
User findByEmailAddress(String emailAddress); <4>
118-
119-
@Procedure(value = "sp_add")
120-
Integer providedProcedure(@Param("arg") Integer arg); <5>
121-
}
122-
----
123-
124-
<1> Derived query without arguments.
125-
<2> Derived query using pagination.
126-
<3> Annotated query.
127-
<4> Named query.
128-
<5> Stored procedure with a provided procedure name.
129-
While stored procedure methods are included in JSON metadata, their method code blocks are not generated in AOT repositories.
130-
====
131-
132-
[source,json]
133-
----
134-
{
135-
"name": "com.acme.UserRepository",
136-
"module": "JPA",
137-
"type": "IMPERATIVE",
138-
"methods": [
139-
{
140-
"name": "findUserNoArgumentsBy",
141-
"signature": "public abstract java.util.List<com.acme.User> com.acme.UserRepository.findUserNoArgumentsBy()",
142-
"query": {
143-
"query": "SELECT u FROM com.acme.User u"
144-
}
145-
},
146-
{
147-
"name": "findPageOfUsersByLastnameStartingWith",
148-
"signature": "public abstract org.springframework.data.domain.Page<com.acme.User> com.acme.UserRepository.findPageOfUsersByLastnameStartingWith(java.lang.String,org.springframework.data.domain.Pageable)",
149-
"query": {
150-
"query": "SELECT u FROM com.acme.User u WHERE u.lastname LIKE ?1 ESCAPE '\\'",
151-
"count-query": "SELECT COUNT(u) FROM com.acme.User u WHERE u.lastname LIKE ?1 ESCAPE '\\'"
152-
}
153-
},
154-
{
155-
"name": "findAnnotatedQueryByEmailAddress",
156-
"signature": "public abstract com.acme.User com.acme.UserRepository.findAnnotatedQueryByEmailAddress(java.lang.String)",
157-
"query": {
158-
"query": "select u from User u where u.emailAddress = ?1"
159-
}
160-
},
161-
{
162-
"name": "findByEmailAddress",
163-
"signature": "public abstract com.acme.User com.acme.UserRepository.findByEmailAddress(java.lang.String)",
164-
"query": {
165-
"name": "User.findByEmailAddress",
166-
"query": "SELECT u FROM User u WHERE u.emailAddress = ?1"
167-
}
168-
},
169-
{
170-
"name": "providedProcedure",
171-
"signature": "public abstract java.lang.Integer com.acme.UserRepository.providedProcedure(java.lang.Integer)",
172-
"query": {
173-
"procedure": "sp_add"
174-
}
175-
},
176-
{
177-
"name": "count",
178-
"signature": "public abstract long org.springframework.data.repository.CrudRepository.count()",
179-
"fragment": {
180-
"fragment": "org.springframework.data.jpa.repository.support.SimpleJpaRepository"
181-
}
182-
}
183-
]
184-
}
185-
----
186-
187-
Queries may contain the following fields:
188-
189-
* `query`: Query descriptor if the method is a query method.
190-
** `name`: Name of the named query if the query is a named one.
191-
** `query` the query used to obtain the query method result from `EntityManager`
192-
** `count-name`: Name of the named count query if the count query is a named one.
193-
** `count-query`: The count query used to obtain the count for query methods using pagination.
194-
** `procedure-name`: Name of the named stored procedure if the stored procedure is a named one.
195-
** `procedure`: Stored procedure name if the query method uses stored procedures.
196-
* `fragment`: Target fragment if the method call is delegated to a store (repository base class, functional fragment such as Querydsl) or user fragment.
197-
Fragments are either described with just `fragment` if there is no further interface or as `interface` and `fragment` tuple in case there is an interface (such as Querydsl or user-declared fragment interface).
198-
199-
[NOTE]
200-
.Normalized Query Form
201-
====
202-
Static analysis of queries allows only a limited representation of runtime query behavior.
203-
Queries are represented in their normalized (pre-parsed and rewritten) form:
204-
205-
* Value Expressions are replaced with bind markers.
206-
* Queries follow the specified query language (JPQL or native) and do not represent the final SQL query.
207-
Spring Data cannot derive the final SQL queries as this is database-specific and depends on the actual runtime environment and parameters (e.g. Entity Graphs, Lazy Loading).
208-
* Query Metadata does not reflect bind-value processing.
209-
`StartingWith`/`EndingWith` queries prepend/append the wildcard character `%` to the actual bind value.
210-
* Runtime Sort information cannot be incorporated in the query string itself as that detail is not known at build-time.
211-
====

0 commit comments

Comments
 (0)