skip to Main Content

Delete Operation is not working. How can i fetch data and then delete it in a functional way? The code successfully run but it is not deleting data in database.

Controller Class

    @DeleteMapping("/deleteUserById/{userId}")
    public Mono<ResponseEntity<String>> deleteUserById(@PathVariable Long userId) {
        return userService.deleteUserById(userId);
    }

UserService Class

    @Override
    public Mono<ResponseEntity<String>> deleteUserById(Long userId) {
        return userRepository.findById(userId)
                .map(user -> {
                    UserDto deletedUser = UserMapper.USER_MAPPER_INSTANCE.toUserDto(user);
                    return "User: " + deletedUser.getUsername() + " deleted!";
                })
                .doOnNext(user -> {
                    userRepository.deleteUserById(userId);
                })
                .map(ResponseEntity::ok)
                .defaultIfEmpty(ResponseEntity
                      .status(HttpStatus.NOT_FOUND)
                      .body("UserId: " +       userId + " Not found"));

   }

Repostiory Interface

@EnableR2dbcRepositories
public interface UserRepository extends ReactiveCrudRepository<User, Long> {

    @Query("SELECT * FROM tb_user WHERE username LIKE $1")
    Mono<User> findByUsername(String username);

    @Query("DELETE FROM tb_user WHERE userid = $1")
    Mono<User> deleteUserById(Long userId);

}

Postgres Table

alertsystem=# select * from tb_user;

userid | username | name | email | password | ph_number | date_of_birth | role
——–+———-+—————+—————————-+———-+————+—————+——-

  5 | am0007   | Ajay Maharjan | [email protected] | asdfgh1  | 558955697 | 1999-05-21    | ADMIN

Output

case: not available userId

UserId: 3 Not found

case: available userId

User: am0007 deleted!

I’m trying to delete data in a database in a reactive way. I’m getting expected output but delete operation is not working.

2

Answers


  1. Chosen as BEST ANSWER

    deleteUserById() was returning mono<Void> despite declaring Mono<User>. So what I did was, I changed it into Mono<Void> and then added .thenReturn(user) which returned Mono<User> from the flatMap.

    return userRepository.findById(userId)
                .flatMap(user -> userRepository.deleteUserById(userId).thenReturn(user))
                .map(user -> {
                    log.info("Deleted User: {}", user);
                    return ResponseEntity.status(HttpStatus.OK).body("User: " + user.getUsername() + " deleted!");
                })
                .defaultIfEmpty(ResponseEntity.status(HttpStatus.NOT_FOUND).body("UserId: " + userId + " Not found"));
    

  2. This is because deleteUserById() is a reactive operation. It returns Mono, but you call it within doOnNext() method, so nobody never subsribes to it. Remember the rule: nothing happens until you subscribe

    The thing is that doOnNext() is meant just to put some side effect, for example, to log something.

    You should call your delete method inside flatMap() operator

    .flatMap(user -> {
        userRepository.deleteUserById(userId);
    })
    

    So downstream subsribes to Mono returned from that flatMap

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search