I am creating a web application for learning purpose using spring web flux, I have a function which first checks if records exits then it updates it else it throws custom NotFoundException. The issue is when i return Mono the controller throws 404 error but when i return the class object which was updated it runs fine and i don't want to return whole object.
The following code runs fine
public Mono<Application> publish(String id,boolean publish)
{
return appRepository.findById(id).flatMap( a -> {
a.setPublished(publish);
return appRepository.save(a);
}).switchIfEmpty( Mono.error(new NotFoundException("Application Not Found")));
}
and below code where 404 error occurs
public Mono<Void> publish(String id,boolean publish)
{
return appRepository.findById(id).flatMap( a -> {
a.setPublished(publish);
appRepository.save(a);
return Mono.empty().then();
}).switchIfEmpty( Mono.error(new NotFoundException("Application Not Found")));
}
I have extended the repository from ReactiveMongoRepository and controller class is just calling the service function
@PutMapping(APP_ROOT_URL + "/{id}/publish")
public Mono<Void> publish(@PathVariable("id") String id)
{
return appService.publish(id, true);
}
The first method doesnt return 404 because:
appRepository.save(a) returns the persisted entity. Not an empty mono. So the switchIfEmpty clause is not triggered.
This is from the doc of ReactiveCrudRepository (one of the parent repositories of ReactiveMongoRepository)
/**
* Saves a given entity. Use the returned instance for further operations as the save operation might have changed the
* entity instance completely.
*
* @param entity must not be {@literal null}.
* @return {@link Mono} emitting the saved entity.
* @throws IllegalArgumentException in case the given {@literal entity} is {@literal null}.
*/
<S extends T> Mono<S> save(S entity);
In second method, you are explicitly returning empty mono. That is why the switchIfEmpty clause is triggered.
One more thing, I would like to point out: The switchIfEmpty clause is not placed correctly . Since findById
returns an empty mono if record is not found for an id, switchIfEmpty
should come after that. If you place switchIfEmpty
after save
, it will never return an empty mono.
So you should have something like this:
public Mono<Application> publish(String id,boolean publish)
{
return appRepository.findById(id)
.switchIfEmpty( Mono.error(new NotFoundException("Application Not Found")))
.flatMap( a -> {
a.setPublished(publish);
return appRepository.save(a);
});
}
And if you want the return type of the method to be Mono<Void>
then simply have something like this:
public Mono<Void> publish(String id, boolean publish)
{
return appRepository.findById(id)
.switchIfEmpty( Mono.error(new NotFoundException("Application Not Found")))
.flatMap( a -> {
a.setPublished(publish);
return appRepository.save(a);
})
.then();
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.