Search code examples
spring-bootcassandraspring-data-cassandra

Spring-data-reactive-cassandra deleteById have no impact


Java: 20.0.0

Springboot: 3.0.1

Cassandra: 4.0

public interface UserRepository extends ReactiveCassandraRepository<User, UUID> {    
}

method call

@Service
public class UserService {
            
   @Autowired
   UserRepository userRepository;
            
   public Mono<Void> removeIfExistingUser(UserRequest userRequest) {
       String userId = userRequest.getUserId();
       String assetType = userRequest.geAssetType();
       String assetId = userRequest.getAssetId();
     
       Flux<User> userFlux = userRepository.findByUserIdAndAssetTypeAndAssetId(userId, assetType, assetId);
       List<User> userList = userFlux.collectList().block();
    
       if (!userList.isEmpty()) {
         User user = userList.get(0);
         Mono<Void> userMono = userRepository.deleteById(user.getId());
         userMono.subscribe();
       }
       return null;
      }
 }

Delete is not working, there is no error nothing, but record is still available in database.


Solution

  • The problem is that you are trying to shoehorn declarative programming into reactive programming/stream processing. Which doesn't really work well. Your service should look something like this (from the top of my head so you might need to switch around some map/flatMap).

    @Service
    public class UserService {
    
        @Autowired
        UserRepository userRepository;
    
        public Mono < Void > removeIfExistingUser(UserRequest userRequest) {
            String userId = userRequest.getUserId();
            String assetType = userRequest.geAssetType();
            String assetId = userRequest.getAssetId();
    
            Flux < User > users = userRepository.findByUserIdAndAssetTypeAndAssetId(userId, assetType, assetId);
            return users.map( User::getId)
                 .flatMap( userRepository::deleteById)
                 .defaultIfEmpty(Mono.empty())
                 .last()
        }
    }
    

    This will retrieve the users, convert the user(s) to id and call the delete method. It will return the last Mono<Void> or a default empty one. Now if the caller of the removeIfExistingUser calls subscribe it will work. If that is a controller from Spring MVC/WebFlux you can just return the Mono<Void> and the web classes will automatically subscribe.