Issue
I am developing a reactive application using Spring Boot 2.3.0, MongoDB, and Kotlin. Unlikely, I need to develop a custom repository using the ReactiveMongoTemplate
object. Since all the application uses Kotlin coroutines, I will be very happy if also this repository could use them.
For example, I developed a simple update on a Mongo collection:
override suspend fun addQuantityToStockInAPortfolio(
portfolio: String,
stock: String,
quantity: Long): UpdateResult? {
return mongo.updateFirst(
Query.query(Criteria.where("_id").isEqualTo(portfolio)),
Update().inc("stocks.$stock", quantity),
MongoPortfolio::class.java
).block()
}
The only way I found to translate a Mono<T>
into the return type of a suspend fun
is to call the block()
method on it.
Is there a more natural way to proceed?
Solution
Yes, there is. block()
is not idiomatic and can lead to problems by blocking a thread which is not supposed to be blocked.
You should use one of the await extension functions like awaitSingle()
which will not block the thread, just suspend instead.
import kotlinx.coroutines.reactive.awaitSingle
// other code
override suspend fun addQuantityToStockInAPortfolio(
portfolio: String,
stock: String,
quantity: Long): UpdateResult {
return mongo.updateFirst(
Query.query(Criteria.where("_id").isEqualTo(portfolio)),
Update().inc("stocks.$stock", quantity),
MongoPortfolio::class.java
).awaitSingle()
}
Answered By - Martin Tarjányi
Answer Checked By - Mary Flores (JavaFixing Volunteer)