5 回答
TA贡献1813条经验 获得超2个赞
经过额外的测试,并考虑了其他开发人员的反馈,我得出了以下解决方案:
public Mono<User> insertUser(User user) {
return userRepository.findByUsername(user.username())
.flatMap(__ -> Mono.error(new DuplicateResourceException("User already exists with username [" + user.username() + "]")))
.switchIfEmpty(Mono.defer(() -> userRepository.insertUser(user)))
.cast(User.class);
}
正如托马斯所说,编译器变得混乱。我的假设是因为flatMap返回一个带有错误的 Mono,并且switchIfEmpty返回一个带有用户的 Mono,因此它恢复为带有对象的 Mono(因此.cast需要额外的运算符来编译它)。
另一个添加是Mono.defer在switchMap. 否则,switchIfEmpty总是会开火。
我仍然愿意接受其他建议/替代方案(因为这似乎是一个相当普遍的需求/模式)。
TA贡献1827条经验 获得超7个赞
我正在使用具有类型参数的抽象类,E
因此我无法使用.cast(E.class)
. 我们的解决方案是
private Mono<E> checkIfStatementExists(E statement) { return this.statementService.getByStatementRequestId(statement.getStatementRequestId()) .flatMap(sr -> Mono.<E>error(new ValidationException("Statement already exists for this request!"))) .switchIfEmpty(Mono.just(statement)); }
我想下周我需要和同事们讨论一下这个问题。
编辑。我们与同事进行了讨论,更新的代码如下。
TA贡献1900条经验 获得超5个赞
为什么您会收到此编译器错误是由于以下原因。
flatmap获取您已完成的内容Mono并尝试将其转换为它可以推断的任何类型。Mono.error包含一个类型,并且该类型是Object。
一种方法是将您的逻辑移至平面图中。
// This is just example code using strings instead of repos
public Mono<String> insertUser(String user) {
return Mono.just(user)
// Here we map/convert instead based on logic
.flatMap(__ -> {
if (__.isEmpty())
return Mono.error(new IllegalArgumentException("User already exists with username [" + user + "]"));
return Mono.just(user);
}).switchIfEmpty(Mono.just(user));
}
switchIfEmpty恕我直言,不太适合做出逻辑决策。文档指出
如果此单声道在没有数据的情况下完成,则回退到替代 Mono
如果我们没有得到任何东西,这更像是一种后备措施,这样我们就可以保持数据流的继续。
你也可以
Mono.empty().doOnNext(o -> {
throw new IllegalArgumentException("User already exists with username [" + o + "]");
}).switchIfEmpty(Mono.just("hello")).subscribe(System.out::println);
TA贡献1820条经验 获得超2个赞
遇到了同样的问题,最后做了下面的事情,
请注意:这不需要类型转换并且适用于两种情况,即
如果数据库中已存在元素,则抛出错误。
插入元素,否则返回 Mono。
public Mono<UserDTO> insertUser(User user) {
return this.userRepository.findByUsername(user.getUsername())
.flatMap(foundUser-> null != foundUser ? Mono
.error(new UserAlreadyExistsException(ExceptionsConstants.USER_ALREADY_EXISTS_EXCEPTION))
: Mono.just(user))
.switchIfEmpty(this.userRepository.save(user))
.map(userCreated -> copyUtils.createUserDTO(userCreated));
}
TA贡献1789条经验 获得超10个赞
可以通过使用一些 Java 通用魔法以 的形式Mono::cast指定 的类型来解决这个问题,而不是使用 来更改 Mono 的类型。这还有一个额外的优点,即您不需要通过向具有 null 处理的方法添加逻辑来更改 Mono 管道的流程,但实际上永远不会接收 null。Mono.errorMono.<User>error(...)flatMap
这看起来如下:
public Mono<User> insertUser(User user) {
return userRepository.findByUsername(user.username())
.flatMap(__ -> Mono.<User>error(new DuplicateResourceException("User already exists with username [" + user.username() + "]")))
.switchIfEmpty(userRepository.insertUser(user));
}
添加回答
举报