spring-data-mongodb icon indicating copy to clipboard operation
spring-data-mongodb copied to clipboard

Reactive Mongo with Kotlin suspend functions

Open BarracudaX opened this issue 4 years ago • 2 comments

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!

BarracudaX avatar Nov 16 '21 19:11 BarracudaX

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.

mp911de avatar Jan 25 '22 10:01 mp911de

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.

sdeleuze avatar Mar 15 '22 12:03 sdeleuze