Hi Spring channel! I am having issue, building Rea...
# spring
a
Hi Spring channel! I am having issue, building ReactiveEndpoint:
Copy code
@PostMapping(SEARCH_ROUTE)
fun search(@RequestBody searchQuery: SearchQuery): Mono<SearchQuery> = searchService.save(searchQuery)
save(searchQuery)
returns Mono<SearchQuery>. When i return Mono.just(searchQuery), there are no issues. But when i return
someMono.flatMap { ... }
I am getting an error:
...SearchQuery cannot be cast to class java.lang.String
Are there any tricks, or i miss something, when i use
.flatMap
? 🙂
c
This isn't Kotlin related. That said, your description is not enough to diagnose the problem. What's going on in the
flatMap
? And where are you trying to return the result of it? Are you returning it from
SearchService#save(searchQuery: SearchQuery)
?
In case of flatMap, if you want the result to be a
Mono<Something>
, you have to make sure that the result of the expression(s) between the curly braces of the
flatMap
to be
Mono<Something>
. If you do not want to construct
Mono
inside
flatMap
, use
map
instead. E.g.
Copy code
class SearchQuery
class SearchQueryPrecursor {
	fun toSearchQuery() : SearchQuery = SearchQuery()
}

class SearchService {
	fun save1(searchQuery: SearchQuery): Mono<SearchQuery> =
		Mono.just(SearchQueryPrecursor().toSearchQuery())
	
	fun save2(searchQuery: SearchQuery): Mono<SearchQuery> =
			Mono.just(SearchQueryPrecursor()).flatMap { Mono.just(it.toSearchQuery()) }
	
	fun save3(searchQuery: SearchQuery): Mono<SearchQuery> =
			Mono.just(SearchQueryPrecursor()).map { it.toSearchQuery() }
}
a
Thank you for the Reply! from the
SearchService#save(searchQuery: SearchQuery)
i am returning:
Copy code
// Mono<Boolean>
        return caches.searchQuery.store(cacheKey, preparedQuery).flatMap {
            result ->
                if (!result) {
                    Mono.error(ErrorSavingSearchQuery("Cannot save query: ${preparedQuery.buildQueryString()}"))
                } else {
                    Mono.just(preparedQuery)
                }
        }
c
I see, your problem is
Mono.just(preparedQuery)
, where
preparedQuery
is probably a
String
, while you specified the expected result to be a
Mono<SearchQuery>
a
uh,
preparedQuery
is the instance of
SearchQuery
and also
if i do something like
return Mono.just(preparedQuery)
before the
flatMap
, everything works fine 😕
i also see, that flatMap returns
MonoFlatMap
object, maybe later internally something weird happens inside the Spring framework
so i guess you are right, its not Kotlin related, have to dig deeper by myself 🙂
c
Sounds strange. I've tried to emulate your problem, but it works as expected for this small script:
Copy code
import reactor.core.publisher.Mono

class SearchQuery {
	override fun toString(): String = "A Test"
	fun buildQueryString() = "ZZZ"
}

class ErrorSavingSearchQuery(message: String) : Throwable(message)

class SearchService {
	fun save(searchQuery: SearchQuery): Mono<SearchQuery> {
		val preparedQuery: SearchQuery = SearchQuery()
		return Mono.just(true).flatMap { result ->
			if (!result) {
				Mono.error(ErrorSavingSearchQuery("Cannot save query: ${preparedQuery.buildQueryString()}"))
			} else {
				Mono.just(preparedQuery)
			}
		}
	}
}

fun test() {
	val result: Mono<SearchQuery> = SearchService().save(searchQuery = SearchQuery())
	result.doOnSuccess {
		println("Hi, it's $it")
	}.subscribe()
}

test()
It prints
Hi, it's A Test
a
i found an issue
caches.searchQuery.store
calls
ReactiveRedisTemplate.opsForValue().set()
, which actually returns
MonoDefer
c
Ah, good 🙂
a
where basically it should return
Mono<Boolean>
in the end
Mono<Boolean> set(K key, V value);
so just need to handle the MonoDefer case properly 😄
but thank you for looking into it also!
In the end it was issue of the proper serialisation of Object to Redis, hehe