英文:
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> {
}
方法调用
@Service
public class UserService {
@Autowired
UserRepository userRepository;
public Mono<Void> removeIfExistingUser(UserRequest userRequest) {
String userId = userRequest.getUserId();
String assetType = userRequest.getAssetType();
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;
}
}
删除不起作用,没有错误,但数据库中仍然存在记录。
英文:
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.
答案1
得分: 1
问题在于你试图将声明式编程强行嵌入响应式编程/流处理中,这并不是一个很好的做法。你的服务应该看起来像这样(我临时想出来的,所以你可能需要在一些 map
/flatMap
上进行调整)。
@Service
public class UserService {
@Autowired
UserRepository userRepository;
public Mono<Void> removeIfExistingUser(UserRequest userRequest) {
String userId = userRequest.getUserId();
String assetType = userRequest.getAssetType();
String assetId = userRequest.getAssetId();
Flux<User> users = userRepository.findByUserIdAndAssetTypeAndAssetId(userId, assetType, assetId);
return users.map(User::getId)
.flatMap(userRepository::deleteById)
.defaultIfEmpty(Mono.empty())
.last();
}
}
这将检索用户,将用户转换为 id,并调用删除方法。它将返回最后一个 Mono<Void>
或一个默认的空 Mono
。现在,如果调用 removeIfExistingUser
的调用者调用 subscribe,它将起作用。如果这是Spring MVC/WebFlux的控制器,你可以直接返回 Mono<Void>
,Web类将自动订阅。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论