Java: 20.0.0
Springboot: 3.0.1
Cassandra: 4.0
public interface UserRepository extends ReactiveCassandraRepository<User, UUID> {
}
@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.
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.