0

I am still a newbie on reactive programming, and I am running a test program using Spring Boot R2DBC on a MariaDB database. The database that I am using is pretty simple:

CREATE DATABASE IF NOT EXISTS `bugdemo`;
USE `bugdemo`;

CREATE TABLE IF NOT EXISTS `persons` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `firstname` varchar(50) DEFAULT NULL,
  `lastname` varchar(50) DEFAULT NULL,
  `title` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;

The class representing my data is below:

@NoArgsConstructor
@Data
@Table(name = "persons")
public class DataDAO
{
   @Id
   private Long id;
   private String firstname;
   private String lastname;
   private String title;

   public DataDAO(String first,String last,String atitle)
   {
      id = null;
      firstname = first;
      lastname = last;
      title = atitle;
   }
}

From my Spring Boot application I have a repository that does nothing special:

public interface BugRepository extends ReactiveCrudRepository<DataDAO, Long>
{
}

And I am running a test application based on an example that I read on the Internet:

@SpringBootTest
class SavebugApplicationTests 
{
   @Autowired
   private BugRepository theRepo;

    @Test
    void testAddOneRecord() 
    {
       DataDAO dao = new DataDAO("Joe","User","Employee");
   
       Mono<DataDAO> row = theRepo.save(dao);
   
       row.doOnNext(next->{
          System.out.println("Data is saved to ID: "+next.getId());
       })
       .doOnSuccess(saved->{
         System.out.println("Saved data. ID="+saved.getId());
      });
   
       DataDAO check = row.block();

      System.out.println("We are here!");
    }
}

Based on my understanding of how this should work, the block() method should make the test block until the signal that there is data returned to the row object. What should happen (based on my understanding) is that the onNext method should print out the "Data was saved" when the data is returned, and the doOnSuccess() method should print the "Saved Data" message when everything was successfully completed. The "We are here" message is just to make sure the println() method is working properly.

What is actually happening is that the save() method is saving the DataDAO object successfully (I am seeing the data appear in the database!), but neither the doOnNext() nor the doOnSuccess methods are being called.

In other words, instead of seeing:

Data is saved to ID: <the_id>
Saved data. ID=<the_id>
We are here!

instead I am seeing:

We are here!

Obviously, my understanding is inaccurate.

Can someone tell me what I am doing wrong here? Am I missing something?

Factor Three
  • 2,094
  • 5
  • 35
  • 51

1 Answers1

0

Yes, my understanding was inaccurate.

What I was missing is the fact that when a Mono (or a Flux) calls a method that returns a Mono, it actually returns a new Mono, not the same one. So when I did the calls as below:

   Mono<DataDAO> row = theRepo.save(dao);

   row.doOnNext(next->{
      System.out.println("Data is saved to ID: "+next.getId());
   })
   .doOnSuccess(saved->{
     System.out.println("Saved data. ID="+saved.getId());
  });

   DataDAO check = row.block();

by the time I reached the block() method, the Mono object that ran the doOnNext() and doOnSuccess() methods had been twice changed.

To use the row object to block, I have to make sure that it is set to the "latest" Mono. This is apparently why so many people string these methods instead of calling them against a created object. In other words, to make my code behave as expected, I needed to write it as follows:

   Mono<DataDAO> row = theRepo.save(dao)
                              .doOnNext(next->{
                                  System.out.println("Data is saved to ID: "+next.getId());
                               })
                               .doOnSuccess(saved->{
                                  System.out.println("Saved data. ID="+saved.getId());
                               });

   DataDAO check = row.block();

Hopefully, this answer will help any others who make a similar mistake...

Factor Three
  • 2,094
  • 5
  • 35
  • 51