Kotlin响应式Mongo仓库suspend查询不存在数据返回null如何处理
问题原因解析
Spring Data MongoDB 从 2.2 版本开始原生支持协程 suspend 类型的 Repository 查询方法,你的声明方式本身符合官方规范。查询不存在的 id 时返回 null 而非抛出 DataAccessException,是 Spring Data 针对 Kotlin 协程场景的默认适配逻辑:底层会自动将空结果映射为 null,遵循 Kotlin 的空安全设计,不会像 Mono.awaitSingle() 那样默认抛出空结果异常。
另外你当前的临时解决方案存在递归调用的缺陷:自定义的 findEntityById 内部调用了同名方法,会触发无限递归导致栈溢出,需要区分代理方法和自定义方法的命名才能正常运行。
最优解决方案
根据你的业务场景可以选择以下方案,均比手动封装返回逻辑更简洁规范:
- 场景1:允许查询结果为空
直接将方法返回值声明为可空类型Entity?即可,Kotlin 编译器会强制你在调用侧处理空情况,无需额外封装,是最符合 Kotlin 语言特性的方案:
suspend fun findEntityById(id: String) : Entity?
调用时可以直接用 Kotlin 空安全语法处理:
val entity = repository.findEntityById(id) ?: // 自定义空结果处理逻辑
- 场景2:查询结果必须存在,否则抛异常
不需要手动封装返回逻辑,有两种更简洁的实现方式:- 方法加非空注解
在 Repository 方法上添加@org.springframework.lang.NonNull注解,Spring Data 会自动校验返回值非空,空结果时自动抛出EmptyResultDataAccessException:
- 方法加非空注解
@NonNull suspend fun findEntityById(id: String) : Entity
- 调用侧校验
如果不想修改 Repository 的声明,在调用时用 Kotlin 标准库的requireNotNull方法校验即可:
val entity = requireNotNull(repository.findEntityById(id)) { "id为${id}的实体不存在" }
内容的提问来源于stack exchange,提问作者Barracuda
相关产品推荐
相关产品推荐

