Webflux mongo 保存多个模型

Webflux mongo save multiple models

在我的应用程序中我有服务器和用户,每个用户可以有多个服务器。 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());
        }
    }
}

但是这个 class 目前并不重要,因为用户根本没有保存。

使用的仓库都是普通的ReactiveCrudRepositories

用多个 Mono 反应调用多个存储库的正确方法是什么?

save 调用实际上并没有保存,它正在设置一个可用于保存的反应管道。该操作仅在订阅它时执行:

Mono<User> savedUser = userRepository.save(user);

所以你应该在你的控制器方法中组合各种位,并确保没有反应类型被单独挂起。

您可能已经看到,通过在保存操作之后添加一个 log() 运算符 - 没有任何内容订阅它,因此不会执行该操作。

你的代码应该是这样的(如果你想 return 创建的用户作为响应;如果你不想 return 任何东西,你可以添加最后一个 then() operator 就在最后,让你的控制器方法 return a 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);
            }));
}