I have an old project that I would like to modernize using WebFlux and MongoDB Reactive frameworks but I'm absolutely stuck at the update method. I have no clue what to pass in the subscribe method. The replaceOne call returns a Publisher but how I should handle it? One of the tips I read was about using the SubscriberHelpers class from mongo-java-driver-reactivestreams but it's missing from the recent versions (4.4). Any help would be appreciated.
mongoDatabase.getCollection("players", Player.class).replaceOne(
Filters.eq("email", player.getEmail()),
player,
new ReplaceOptions().upsert(true)
).subscribe( ??? );
Update: I created a DummySubscriber class to manage the subscription which seems working properly.
mongoDatabase.getCollection("players", Player.class).replaceOne(
Filters.eq("email", player.getEmail()),
player,
new ReplaceOptions().upsert(true)
).subscribe(new DummySubscriber<>());
private static class DummySubscriber<T> implements Subscriber<T> {
@Override
public void onSubscribe(Subscription subscription) {
subscription.request(Integer.MAX_VALUE);
}
@Override
public void onNext(T t) {
}
@Override
public void one rror(Throwable throwable) {
System.out.println("Error while updating data");
}
@Override
public void onComplete() {
System.out.println("Data has been updated");
}
}
CodePudding user response:
After looking at your example i could see that the problem is that you are not using the ReactiveMongoTemplate
when doing your calls against the database.
You decided to use the raw MongoDatabase
object, which is more low level which does not provide you with the webflux api.
MongoDatabase
only implement the standard reactivestreams
specification, which does only support something implementing Subscriber<T>
as subscribers.
I recommend not using the low level MongoDatabase
object and instead use the higher level abstractions.
If you are going to use spring webflux you should be using either the ReactiveRepositories
that spring provides, or if you want to be low level use the ReactiveMongoTemplate
private final ReactiveMongoTemplate reactiveMongoTemplate;
@Autowired
public PlayerRepository(ReactiveMongoTemplate reactiveMongoTemplate) {
this.reactiveMongoTemplate = reactiveMongoTemplate;
}
public void savePlayers(Player player) {
final Query query = new Query();
query.addCriteria(Criteria.where("email").is(player.getEmail()));
final Update update = new Update();
update.set("name", player.getName());
update.set("email", player.getEmail());
reactiveMongoTemplate.findAndModify(query, update, Player.class)
.subscribe(
updatedPlayer -> System.out.println("updated player"),
error -> System.out.println("Something went wrong: " error.getCause()),
() -> System.out.println("update is finished"));
}
I strongly suggest you learn how to use regular MongoTemplate
without webflux
before you go on to use webflux
and the ReactiveMongoTemplate
There are several tutorials, about using MongoTemplate
and the ReactiveMongoTemplate
https://www.baeldung.com/spring-data-mongodb-reactive
https://hantsy.github.io/spring-reactive-sample/data/data-mongo.html