spring-data-mongodb
spring-data-mongodb copied to clipboard
Reactive Mongo with Kotlin suspend functions
When writing ReactiveMongoRepository/ReactiveCrudRepository with spring-boot-starter-data-mongodb-reactive and declaring suspend find function with non-nullable kotlin return types, the repository returns null when it can't find an entity instead of EmptyResultDataAccessException.
Here is the fun declaration:
suspend fun findSomeEntitiesById(id: Long): SomeEntity
And this test prints null when called with id that does not exists:
@Test internal fun returnsNllReference() { runBlocking { println(repositoryMy.findSomeEntitiesById(123)) } }
If I replace spring-boot-starter-data-mongodb-reactive with spring-boot-starter-data-r2dbc, it throws
org.springframework.dao.EmptyResultDataAccessException: Result must not be null!
The MethodInvocationValidator introspects the return value from coroutine invocations. In that case we see CoroutineSingletons.COROUTINE_SUSPENDED being returned and we cannot perform any further validations. I'm not sure how to proceed here. Maybe @sdeleuze can provide additional guidance on how to either intercept the continuation or how we can post-process the emitted/not-emitted value from the continuation.
This kind of use case may require using Kotlin reflection (via kotlin-reflect) to get the null-safety information, that what we do on Framework side, see https://github.com/spring-projects/spring-framework/blob/main/spring-core/src/main/java/org/springframework/core/MethodParameter.java#L872.
See also related https://github.com/spring-projects/spring-framework/issues/21546#issuecomment-953659196 issue/comment.