此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Data Redis 3.4.4! |
存储库方法的 Null 处理
从 Spring Data 2.0 开始,返回单个聚合实例的存储库 CRUD 方法使用 Java 8 的Optional
以指示可能缺少值。
除此之外, Spring Data 支持在查询方法上返回以下包装器类型:
-
com.google.common.base.Optional
-
scala.Option
-
io.vavr.control.Option
或者,查询方法可以选择根本不使用包装器类型。
然后,通过返回null
.
返回集合、集合替代项、包装器和流的存储库方法保证永远不会返回null
而是相应的空表示。
有关详细信息,请参阅“存储库查询返回类型”。
可为 Null 性注释
您可以使用 Spring Framework 的可为 null 性注释来表达存储库方法的可为 null 性约束。
它们提供了一种工具友好的方法和选择加入null
检查,如下所示:
-
@NonNullApi
:在包级别用于声明参数和返回值的默认行为分别是既不接受也不生成null
值。 -
@NonNull
:用于不得为null
(在参数和返回值上不需要,其中@NonNullApi
适用)。 -
@Nullable
:用于参数或返回值,该参数或返回值可以是null
.
Spring 注解使用 JSR 305 注解(一种休眠但广泛使用的 JSR)进行元注解。
JSR 305 元注释允许工具供应商(例如 IDEA、Eclipse 和 Kotlin)以通用方式提供空安全支持,而不必对 Spring 注释进行硬编码支持。
要启用查询方法的可为 null 性约束的运行时检查,您需要使用 Spring 的@NonNullApi
在package-info.java
,如以下示例所示:
package-info.java
@org.springframework.lang.NonNullApi
package com.acme;
一旦非 null 默认值到位,存储库查询方法调用将在运行时验证是否为 null 性约束。
如果查询结果违反定义的约束,则会引发异常。
当方法返回null
但被声明为不可为空(在存储库所在的包上定义的注释的默认值)。
如果您想再次选择加入可为 null 的结果,请有选择地使用@Nullable
在单个方法上。
使用本节开头提到的结果包装器类型将继续按预期工作:空结果将转换为表示 absence 的值。
以下示例显示了刚才描述的许多技术:
package com.acme; (1)
import org.springframework.lang.Nullable;
interface UserRepository extends Repository<User, Long> {
User getByEmailAddress(EmailAddress emailAddress); (2)
@Nullable
User findByEmailAddress(@Nullable EmailAddress emailAdress); (3)
Optional<User> findOptionalByEmailAddress(EmailAddress emailAddress); (4)
}
1
The repository resides in a package (or sub-package) for which we have defined non-null behavior.
2
Throws an EmptyResultDataAccessException
when the query does not produce a result.
Throws an IllegalArgumentException
when the emailAddress
handed to the method is null
.
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
.
Nullability in Kotlin-based Repositories
Kotlin has the definition of nullability constraints baked into the language.
Kotlin code compiles to bytecode, which does not express nullability constraints through method signatures but rather through compiled-in metadata.
Make sure to include the kotlin-reflect
JAR in your project to enable introspection of Kotlin’s nullability constraints.
Spring Data repositories use the language mechanism to define those constraints to apply the same runtime checks, as follows:
Using nullability constraints on Kotlin repositories
interface UserRepository : Repository<User, String> {
fun findByUsername(username: String): User (1)
fun findByFirstname(firstname: String?): User? (2)
}
1
The method defines both the parameter and the result as non-nullable (the Kotlin default).
The Kotlin compiler rejects method invocations that pass null
to the method.
If the query yields an empty result, an EmptyResultDataAccessException
is thrown.
2
This method accepts null
for the firstname
parameter and returns null
if the query does not produce a result.