You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/main/asciidoc/repositories.adoc
+76
Original file line number
Diff line number
Diff line change
@@ -214,6 +214,82 @@ In this first step you defined a common base interface for all your domain repos
214
214
NOTE: Note, that the intermediate repository interface is annotated with `@NoRepositoryBean`. Make sure you add that annotation to all repository interfaces that Spring Data should not create instances for at runtime.
215
215
216
216
217
+
[[repositories.nullability]]
218
+
=== Null handling of repository methods
219
+
220
+
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.
221
+
Besides that, Spring Data supports to return other wrapper types on query methods:
222
+
223
+
* `com.google.common.base.Optional`
224
+
* `scala.Option`
225
+
* `io.vavr.control.Option`
226
+
* `javaslang.control.Option` (deprecated as Javaslang is deprecated)
227
+
228
+
Alternatively query methods can choose not to use a wrapper type at all.
229
+
The absence of a query result will then be indicated by returning `null`.
230
+
Repository methods returning collection like values will never return null but an empty value.
231
+
232
+
[[repositories.nullability.annotations]]
233
+
==== Nullability annotations
234
+
235
+
To properly validate nullability constraints on a repository method at runtime, annotations can be defined to define whether query methods are supposed to return `null`.
236
+
To enable this, non-nullability needs to be activated on the package level, e.g. using Spring's `@NonNullApi` in `package-info.java`:
237
+
238
+
.Declaring non-nullablity in `package-info.java`
239
+
====
240
+
[source, java]
241
+
----
242
+
@NonNullApi
243
+
package com.acme;
244
+
----
245
+
====
246
+
247
+
Once that is in place, repository query method will get runtime execution validation of the nullability constraints and exceptions will be thrown in case a query execution result violates the defined constrained, i.e. the method would return `null` for some reason but is declared as non-nullable (the default with the annotation defined on the package the repository resides in).
248
+
If you want to opt-in to nullable results again, e.g. `@Nullable` can be used on a method selectively.
249
+
Using the aforementioned result wrapper types will continue to work as expected, i.e. an empty result will be translated into the value representing absence.
<1> Will throw an `EmptyResultDataAccessException` in case the query executed does not produce a result. Will throw an `IllegalArgumentException` in case the `emailAddress` handed to the method is `null`.
268
+
<2> Will return `null` in case the query executed does not produce a result. Also accepts `null` as value for `emailAddress`.
269
+
<3> Will return `Optional.empty()` in case the query executed does not produce a result. Will throw an `IllegalArgumentException` in case the `emailAddress` handed to the method is `null`.
270
+
====
271
+
272
+
[[repositories.nullability.kotlin]]
273
+
==== Nullability in Kotlin-based repositories
274
+
275
+
Kotlin has the definition of nullability constraints baked into the language.
276
+
Spring Data repositories using the language mechanism to define those constraints will automatically get the same runtime checks applied:
277
+
278
+
.Using nullability constraints on Kotlin repositories
fun findByFirstname(firstname: String?): User? <2>
287
+
}
288
+
----
289
+
<1> The method defines both the parameter as non-nullable (the Kotlin default) as well as the result. The Kotlin compiler will already reject method invocations trying to hand `null` into the method. In case the query execution yields an empty result, an `EmptyResultDataAccessException` will be thrown.
290
+
<2> This method accepts `null` as parameter for `firstname` and return `null` in case the query execution does not produce a result.
291
+
====
292
+
217
293
[[repositories.multiple-modules]]
218
294
=== Using Repositories with multiple Spring Data modules
0 commit comments