Skip to content

Commit c20e13f

Browse files
Merge branch 'spring-projects:main' into main
2 parents 37120de + 6ca3170 commit c20e13f

File tree

933 files changed

+6473
-2798
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

933 files changed

+6473
-2798
lines changed

.mvn/wrapper/maven-wrapper.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
#Fri Jun 03 09:32:43 CEST 2022
2-
distributionUrl=https\://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.5/apache-maven-3.8.5-bin.zip
1+
#Tue Jun 13 08:54:57 CEST 2023
2+
distributionUrl=https\://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.2/apache-maven-3.9.2-bin.zip

Jenkinsfile

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
def p = [:]
22
node {
3-
checkout scm
4-
p = readProperties interpolate: true, file: 'ci/pipeline.properties'
3+
checkout scm
4+
p = readProperties interpolate: true, file: 'ci/pipeline.properties'
55
}
66

77
pipeline {
@@ -18,7 +18,7 @@ pipeline {
1818
}
1919

2020
stages {
21-
stage("test: baseline (Java 17)") {
21+
stage("test: baseline (main)") {
2222
when {
2323
beforeAgent(true)
2424
anyOf {
@@ -42,6 +42,34 @@ pipeline {
4242
}
4343
}
4444

45+
stage("Test other configurations") {
46+
when {
47+
beforeAgent(true)
48+
allOf {
49+
branch(pattern: "main|(\\d\\.\\d\\.x)", comparator: "REGEXP")
50+
not { triggeredBy 'UpstreamCause' }
51+
}
52+
}
53+
parallel {
54+
stage("test: baseline (next)") {
55+
agent {
56+
label 'data'
57+
}
58+
options { timeout(time: 30, unit: 'MINUTES') }
59+
environment {
60+
ARTIFACTORY = credentials("${p['artifactory.credentials']}")
61+
}
62+
steps {
63+
script {
64+
docker.image(p['docker.java.next.image']).inside(p['docker.java.inside.basic']) {
65+
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml clean dependency:list verify -Dsort -U -B'
66+
}
67+
}
68+
}
69+
}
70+
}
71+
}
72+
4573
stage('Release to artifactory') {
4674
when {
4775
beforeAgent(true)

ci/pipeline.properties

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
# Java versions
2-
java.main.tag=17.0.4.1_1-jdk-focal
2+
java.main.tag=17.0.6_10-jdk-focal
3+
java.next.tag=20-jdk-jammy
34

45
# Docker container images - standard
56
docker.java.main.image=harbor-repo.vmware.com/dockerhub-proxy-cache/library/eclipse-temurin:${java.main.tag}
7+
docker.java.next.image=harbor-repo.vmware.com/dockerhub-proxy-cache/library/eclipse-temurin:${java.next.tag}
68

79
# Supported versions of MongoDB
8-
docker.mongodb.4.4.version=4.4.17
9-
docker.mongodb.5.0.version=5.0.13
10-
docker.mongodb.6.0.version=6.0.2
10+
docker.mongodb.4.4.version=4.4.18
11+
docker.mongodb.5.0.version=5.0.14
12+
docker.mongodb.6.0.version=6.0.4
1113

1214
# Supported versions of Redis
13-
docker.redis.6.version=6.2.6
15+
docker.redis.6.version=6.2.10
1416

1517
# Supported versions of Cassandra
1618
docker.cassandra.3.version=3.11.14

pom.xml

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
<groupId>org.springframework.data</groupId>
77
<artifactId>spring-data-commons</artifactId>
8-
<version>3.0.0-SNAPSHOT</version>
8+
<version>3.2.0-SNAPSHOT</version>
99

1010
<name>Spring Data Core</name>
1111
<description>Core Spring concepts underpinning every Spring Data module.</description>
@@ -25,7 +25,7 @@
2525
<parent>
2626
<groupId>org.springframework.data.build</groupId>
2727
<artifactId>spring-data-parent</artifactId>
28-
<version>3.0.0-SNAPSHOT</version>
28+
<version>3.2.0-SNAPSHOT</version>
2929
</parent>
3030

3131
<properties>
@@ -366,16 +366,19 @@
366366

367367
<repositories>
368368
<repository>
369-
<id>spring-libs-snapshot</id>
370-
<url>https://repo.spring.io/libs-snapshot</url>
369+
<id>spring-snapshot</id>
370+
<url>https://repo.spring.io/snapshot</url>
371+
<snapshots>
372+
<enabled>true</enabled>
373+
</snapshots>
374+
<releases>
375+
<enabled>false</enabled>
376+
</releases>
377+
</repository>
378+
<repository>
379+
<id>spring-milestone</id>
380+
<url>https://repo.spring.io/milestone</url>
371381
</repository>
372382
</repositories>
373383

374-
<pluginRepositories>
375-
<pluginRepository>
376-
<id>spring-plugins-release</id>
377-
<url>https://repo.spring.io/plugins-release</url>
378-
</pluginRepository>
379-
</pluginRepositories>
380-
381384
</project>

src/main/asciidoc/dependencies.adoc

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ The version name follows `${calver}` for GA releases and service releases and th
3030
* `M1`, `M2`, and so on: Milestones
3131
* `RC1`, `RC2`, and so on: Release candidates
3232

33-
You can find a working example of using the BOMs in our https://github.com/spring-projects/spring-data-examples/tree/master/bom[Spring Data examples repository]. With that in place, you can declare the Spring Data modules you would like to use without a version in the `<dependencies />` block, as follows:
33+
You can find a working example of using the BOMs in our https://github.com/spring-projects/spring-data-examples/tree/main/bom[Spring Data examples repository]. With that in place, you can declare the Spring Data modules you would like to use without a version in the `<dependencies />` block, as follows:
3434

3535
.Declaring a dependency to a Spring Data module
3636
====
@@ -48,8 +48,12 @@ You can find a working example of using the BOMs in our https://github.com/sprin
4848
[[dependencies.spring-boot]]
4949
== Dependency Management with Spring Boot
5050

51-
Spring Boot selects a recent version of Spring Data modules for you. If you still want to upgrade to a newer version, set
52-
the `spring-data-releasetrain.version` property to the <<dependencies.train-version,train version and iteration>> you would like to use.
51+
Spring Boot selects a recent version of the Spring Data modules for you. If you still want to upgrade to a newer version,
52+
set the `spring-data-bom.version` property to the <<dependencies.train-version,train version and iteration>>
53+
you would like to use.
54+
55+
See Spring Boot's https://docs.spring.io/spring-boot/docs/current/reference/html/dependency-versions.html#appendix.dependency-versions.properties[documentation]
56+
(search for "Spring Data Bom") for more details.
5357

5458
[[dependencies.spring-framework]]
5559
== Spring Framework

src/main/asciidoc/index.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
Oliver Gierke; Thomas Darimont; Christoph Strobl; Mark Pollack; Thomas Risberg; Mark Paluch; Jay Bryant
33
:revnumber: {version}
44
:revdate: {localdate}
5+
:feature-scroll: true
56
ifdef::backend-epub3[:front-cover-image: image:epub-cover.png[Front Cover,1050,1600]]
67

78
(C) 2008-2022 The original authors.

src/main/asciidoc/kotlin.adoc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ This comprehensive https://spring.io/guides/tutorials/spring-boot-kotlin/[tutori
1111
[[kotlin.requirements]]
1212
== Requirements
1313

14-
Spring Data supports Kotlin 1.3 and requires https://bintray.com/bintray/jcenter/org.jetbrains.kotlin%3Akotlin-stdlib[`kotlin-stdlib`] (or one of its variants, such as https://bintray.com/bintray/jcenter/org.jetbrains.kotlin%3Akotlin-stdlib-jdk8[`kotlin-stdlib-jdk8`]) and https://bintray.com/bintray/jcenter/org.jetbrains.kotlin%3Akotlin-reflect[`kotlin-reflect`] to be present on the classpath.
14+
Spring Data supports Kotlin 1.3 and requires `kotlin-stdlib` (or one of its variants, such as `kotlin-stdlib-jdk8`) and `kotlin-reflect` to be present on the classpath.
1515
Those are provided by default if you bootstrap a Kotlin project via https://start.spring.io/#!language=kotlin&type=gradle-project[start.spring.io].
1616

1717
[[kotlin.null-safety]]
1818
== Null Safety
1919

20-
One of Kotlin's key features is https://kotlinlang.org/docs/reference/null-safety.html[null safety], which cleanly deals with `null` values at compile time.
20+
One of Kotlin's key features is https://kotlinlang.org/docs/null-safety.html[null safety], which cleanly deals with `null` values at compile time.
2121
This makes applications safer through nullability declarations and the expression of "`value or no value`" semantics without paying the cost of wrappers, such as `Optional`.
22-
(Kotlin allows using functional constructs with nullable values. See this https://www.baeldung.com/kotlin-null-safety[comprehensive guide to Kotlin null safety].)
22+
(Kotlin allows using functional constructs with nullable values. See this https://www.baeldung.com/kotlin/null-safety[comprehensive guide to Kotlin null safety].)
2323

2424
Although Java does not let you express null safety in its type system, Spring Data API is annotated with https://jcp.org/en/jsr/detail?id=305[JSR-305] tooling friendly annotations declared in the `org.springframework.lang` package.
2525
By default, types from Java APIs used in Kotlin are recognized as https://kotlinlang.org/docs/reference/java-interop.html#null-safety-and-platform-types[platform types], for which null checks are relaxed.

src/main/asciidoc/object-mapping.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,8 @@ The wither method is optional as the persistence constructor (see 6) is effectiv
203203
<3> The `age` property is an immutable but derived one from the `birthday` property.
204204
With the design shown, the database value will trump the defaulting as Spring Data uses the only declared constructor.
205205
Even if the intent is that the calculation should be preferred, it's important that this constructor also takes `age` as parameter (to potentially ignore it) as otherwise the property population step will attempt to set the age field and fail due to it being immutable and no `with…` method being present.
206-
<4> The `comment` property is mutable is populated by setting its field directly.
207-
<5> The `remarks` properties are mutable and populated by setting the `comment` field directly or by invoking the setter method for
206+
<4> The `comment` property is mutable and is populated by setting its field directly.
207+
<5> The `remarks` property is mutable and is populated by invoking the setter method.
208208
<6> The class exposes a factory method and a constructor for object creation.
209209
The core idea here is to use factory methods instead of additional constructors to avoid the need for constructor disambiguation through `@PersistenceCreator`.
210210
Instead, defaulting of properties is handled within the factory method.

src/main/asciidoc/preface.adoc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ The Spring Data Commons project applies core Spring concepts to the development
77

88
* Version control: https://github.com/spring-projects/spring-data-commons
99
* Bugtracker: https://github.com/spring-projects/spring-data-commons/issues
10-
* Release repository: https://repo.spring.io/libs-release
11-
* Milestone repository: https://repo.spring.io/libs-milestone
12-
* Snapshot repository: https://repo.spring.io/libs-snapshot
10+
* Release repository: https://repo1.maven.org/maven2/
11+
* Milestone repository: https://repo.spring.io/milestone/
12+
* Snapshot repository: https://repo.spring.io/snapshot/
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
[[repositories.nullability]]
2+
=== Null Handling of Repository Methods
3+
4+
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.
5+
Besides that, Spring Data supports returning the following wrapper types on query methods:
6+
7+
* `com.google.common.base.Optional`
8+
* `scala.Option`
9+
* `io.vavr.control.Option`
10+
11+
Alternatively, query methods can choose not to use a wrapper type at all.
12+
The absence of a query result is then indicated by returning `null`.
13+
Repository methods returning collections, collection alternatives, wrappers, and streams are guaranteed never to return `null` but rather the corresponding empty representation.
14+
See "`<<repository-query-return-types>>`" for details.
15+
16+
[[repositories.nullability.annotations]]
17+
==== Nullability Annotations
18+
19+
You can express nullability constraints for repository methods by using {spring-framework-docs}/core.html#null-safety[Spring Framework's nullability annotations].
20+
They provide a tooling-friendly approach and opt-in `null` checks during runtime, as follows:
21+
22+
* {spring-framework-javadoc}/org/springframework/lang/NonNullApi.html[`@NonNullApi`]: Used on the package level to declare that the default behavior for parameters and return values is, respectively, neither to accept nor to produce `null` values.
23+
* {spring-framework-javadoc}/org/springframework/lang/NonNull.html[`@NonNull`]: Used on a parameter or return value that must not be `null` (not needed on a parameter and return value where `@NonNullApi` applies).
24+
* {spring-framework-javadoc}/org/springframework/lang/Nullable.html[`@Nullable`]: Used on a parameter or return value that can be `null`.
25+
26+
Spring annotations are meta-annotated with https://jcp.org/en/jsr/detail?id=305[JSR 305] annotations (a dormant but widely used JSR).
27+
JSR 305 meta-annotations let tooling vendors (such as https://www.jetbrains.com/help/idea/nullable-and-notnull-annotations.html[IDEA], https://help.eclipse.org/latest/index.jsp?topic=/org.eclipse.jdt.doc.user/tasks/task-using_external_null_annotations.htm[Eclipse], and link:https://kotlinlang.org/docs/reference/java-interop.html#null-safety-and-platform-types[Kotlin]) provide null-safety support in a generic way, without having to hard-code support for Spring annotations.
28+
To enable runtime checking of nullability constraints for query methods, you need to activate non-nullability on the package level by using Spring’s `@NonNullApi` in `package-info.java`, as shown in the following example:
29+
30+
.Declaring Non-nullability in `package-info.java`
31+
====
32+
[source,java]
33+
----
34+
@org.springframework.lang.NonNullApi
35+
package com.acme;
36+
----
37+
====
38+
39+
Once non-null defaulting is in place, repository query method invocations get validated at runtime for nullability constraints.
40+
If a query result violates the defined constraint, an exception is thrown.
41+
This happens when the method would return `null` but is declared as non-nullable (the default with the annotation defined on the package in which the repository resides).
42+
If you want to opt-in to nullable results again, selectively use `@Nullable` on individual methods.
43+
Using the result wrapper types mentioned at the start of this section continues to work as expected: an empty result is translated into the value that represents absence.
44+
45+
The following example shows a number of the techniques just described:
46+
47+
.Using different nullability constraints
48+
====
49+
[source,java]
50+
----
51+
package com.acme; <1>
52+
53+
import org.springframework.lang.Nullable;
54+
55+
interface UserRepository extends Repository<User, Long> {
56+
57+
User getByEmailAddress(EmailAddress emailAddress); <2>
58+
59+
@Nullable
60+
User findByEmailAddress(@Nullable EmailAddress emailAdress); <3>
61+
62+
Optional<User> findOptionalByEmailAddress(EmailAddress emailAddress); <4>
63+
}
64+
----
65+
<1> The repository resides in a package (or sub-package) for which we have defined non-null behavior.
66+
<2> Throws an `EmptyResultDataAccessException` when the query does not produce a result.
67+
Throws an `IllegalArgumentException` when the `emailAddress` handed to the method is `null`.
68+
<3> Returns `null` when the query does not produce a result.
69+
Also accepts `null` as the value for `emailAddress`.
70+
<4> Returns `Optional.empty()` when the query does not produce a result.
71+
Throws an `IllegalArgumentException` when the `emailAddress` handed to the method is `null`.
72+
====
73+
74+
[[repositories.nullability.kotlin]]
75+
==== Nullability in Kotlin-based Repositories
76+
77+
Kotlin has the definition of https://kotlinlang.org/docs/reference/null-safety.html[nullability constraints] baked into the language.
78+
Kotlin code compiles to bytecode, which does not express nullability constraints through method signatures but rather through compiled-in metadata.
79+
Make sure to include the `kotlin-reflect` JAR in your project to enable introspection of Kotlin's nullability constraints.
80+
Spring Data repositories use the language mechanism to define those constraints to apply the same runtime checks, as follows:
81+
82+
.Using nullability constraints on Kotlin repositories
83+
====
84+
[source,kotlin]
85+
----
86+
interface UserRepository : Repository<User, String> {
87+
88+
fun findByUsername(username: String): User <1>
89+
90+
fun findByFirstname(firstname: String?): User? <2>
91+
}
92+
----
93+
<1> The method defines both the parameter and the result as non-nullable (the Kotlin default).
94+
The Kotlin compiler rejects method invocations that pass `null` to the method.
95+
If the query yields an empty result, an `EmptyResultDataAccessException` is thrown.
96+
<2> This method accepts `null` for the `firstname` parameter and returns `null` if the query does not produce a result.
97+
====

0 commit comments

Comments
 (0)