Webflux mongo保存多个模型

时间:2017-11-22 10:59:11

标签: spring mongodb reactive project-reactor spring-webflux

在我的应用程序中,我有服务器和用户,每个用户可以拥有多个服务器。 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反应性调用多个存储库的正确方法是什么?

1 个答案:

答案 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);
            }));
}