Search code examples
javaproject-reactorspring-data-r2dbcr2dbc

Find/Modify/Save or Upsert with Spring Data R2DBC


I'm trying to wrap my head around reactive programming, specifically with Spring and Spring Data R2DBC. One thing that would help me understand it better is to do a find/modify/save or "upsert" of an object. A traditional interaction might look like this:

Book save(Book book) {

   Book existing = repository.findByIsbn(book.getIsbn())

   if (existing != null) {
     return repository.save(found.copyMutableValuesFrom(book));
   }

   return repository.save(book);
}

How might this look with Monos? I understand how to do a straight find, or a straight save, but a more complicated find/update/save or upsert is eluding me.

Thanks.


Solution

  • It will be more or less like this for your requirement.

    @Transactional
    Mono<Book> save(Book book){
        return repository.findByIsbn(book.getIsbn())
                        .flatMap(found -> repository.save(found.copyMutableValuesFrom(book)))
                        .switchIfEmpty(repository.save(book));  
    }
    
    1. ReactiveCrudRepository returns Mono<Book> when you call findById(something like Optional<Book> - if it is your custom method, make it return Mono<Book>)
    2. If the book is present second statement is executed where we update the existing book
    3. if the book is not found, 3rd statement is executed where we save the new book.

    It returns a Mono<Book>