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