在我的应用程序中,我有服务器和用户,每个用户可以拥有多个服务器。 User
中的服务器列表是@DBref
:
@DBRef
private List<Server> servers;
在我想要创建服务器的控制器中,我首先创建并保存服务器,之后我将服务器添加到用户的服务器列表中并保存用户:
@PostMapping
public Mono create(@Valid @RequestBody Server server, Mono<Authentication> authentication) {
return this.serverRepository.save(server) // This works, the server is saved.
.and(authentication.map(value -> {
User user = (User) value.getDetails();
System.out.println(user); // This works, so this function is called.
if (user.getServers() == null) {
// Create empty list so .add can be used.
user.setServers(new ArrayList<>());
}
user.getServers().add(server);
return userRepository.save(user); // Isn't working, in the UserCascadeSaveMongoEventListener I don't see it.
}));
}
我认为我使用.and()
的方式不对。
要保存关系,我有UserCascadeSaveMongoEventListener
:
public class UserCascadeSaveMongoEventListener extends AbstractMongoEventListener<Object> {
@Autowired
private MongoOperations mongoOperations;
@Override
public void onBeforeConvert(BeforeConvertEvent<Object> event) {
Object source = event.getSource();
System.out.println(source); // On server create only the Server is shown, User is not shown.
if ((source instanceof User) && (((User) source).getServers() != null)) {
mongoOperations.save(((User) source).getServers());
}
}
}
但是这个课目前并不重要,因为用户根本没有保存。
使用的存储库都是正常的ReactiveCrudRepositories。
使用多个Mono反应性调用多个存储库的正确方法是什么?
答案 0 :(得分:2)
save
调用实际上并未保存,它正在设置一个可用于保存的反应式管道。该操作仅在订阅它时执行:
Mono<User> savedUser = userRepository.save(user);
因此,您应该在控制器方法中编写各个位,并确保不会单独挂起任何反应类型。
您可以通过在保存操作之后添加log()
运算符来看到 - 没有订阅它以便不执行操作。
您的代码应该是这样的(如果您想要将创建的用户作为响应返回;如果您不想返回任何内容,则可以在最后添加最终then()
运算符并使您的controller方法返回一个Mono<Void>
,表示操作完成时的信号):
@PostMapping
public Mono<User> create(@Valid @RequestBody Server server, Mono<Authentication> authentication) {
return this.serverRepository.save(server) // This works, the server is saved.
.then(authentication.flatMap(value -> {
User user = (User) value.getDetails();
System.out.println(user); // This works, so this function is called.
if (user.getServers() == null) {
// Create empty list so .add can be used.
user.setServers(new ArrayList<>());
}
user.getServers().add(server);
return userRepository.save(user);
}));
}