如果不为空,spring rector throw Exception

时间:2019-07-31 20:40:37

标签: spring-boot project-reactor reactive

类似于Spring Reactor: How to throw an exception when publisher emit a value?

我的DAO $user->fullname 中有一个finder方法,该方法返回结果SomePojo。查找程序将调用amazon db api,而java findSomePojo具有调用输出。 因此,我正在尝试在我的服务层中使用hasElement()检查createSomePojo方法。 (不确定我是否正确使用它-我正在尝试和调试)

基本上: 我想检查是否已经有元素,保存是非法的,我不会称其为DAO保存。所以我需要抛出异常。

假设数据库中已经存在SomePojo的记录,我尝试调用service的create_SomePjo。但是我在日志中看到过滤器不起作用,当反应堆调用createModel_SomePojo时,它得到了NPE,这使我相信即使在检查过滤器之后它会抛出NPE

javasoftware.amazon.awssdk.services.dynamodb.model.GetItemResponse

我看到Mono上有hasElement()方法。不知道如何正确使用它。 如果我直接在服务create_SomePojo(reqPojo)中调用DAO保存而不进行所有此查找程序检查,则可以实现异常,因为主键约束将负责并抛出异常,并且我可以重新抛出然后捕获服务,但是如果我想签入该怎么办服务并抛出带有错误代码的异常。这个想法不是将响应错误对象传递到dao层。

2 个答案:

答案 0 :(得分:0)

这段代码有点混乱,但是据我了解,您想在find不返回任何元素时调用保存对象,并在实体已经存在时抛出异常。

我会选择这样的东西:

    Mono<Void> create_SomePojo(reqPojo){
        Mono<Boolean> monoPresent = find_SomePojo(accountId,contentIdExtn)
                .filter(i -> i.getId()!=null)
                .hasElement();
        return monoPresent
                .flatMap(Mono.error(new SomeException(ITEM_ALREADY_EXISTS)))
                .switchIfEmpty(SomePojoRepo.save(reqPojo))
                .then();
    }

让我知道它是否可以解决您的问题。

答案 1 :(得分:0)

尝试使用Hooks.onOperatorDebug()挂钩以获得更好的调试体验。

正确使用hasElement的方式(假设find_SomePojo永远不会返回null)

Mono<Boolean> monoPresent =  find_SomePojo(accountId, contentIdExtn)
        .filter(i -> i.getId() != null)
        .hasElement();

return monoPresent.flatMap(isPresent -> {
    if(isPresent){
        Mono.error(new SomeException(ITEM_ALREADY_EXISTS)));
    }else{
        SomePojoRepo.save(reqPojo);
    }
}).then();

边注

对于Mono的实际含义有一个普遍的误解。它不保存任何数据-只是流水线的一部分,传输流经它的信号和数据。因此,第System.out.println("monoPresent="+monoPresent.toString());行没有意义,因为它只是在现有管道周围打印hasElements()装饰器。装饰器的内部名称为MonoHasElement,无论其中包含什么{true /false),无论如何MonoHasElement都将被打印。

正确的打印信号方式(以及与之一起发送的数据)是: Mono.log()Mono.doOnEach/next(System.out::println)System.out.println("monoPresent="+monoPresent.block());。提防第三个线程:它将阻塞整个线程,直到发出数据为止,所以只有在知道自己在做什么的情况下才使用它。

Monos打印示例可用于:

   Mono<String> abc = Mono.just("abc").delayElement(Duration.ofSeconds(99999999));

    System.out.println(abc); //this will print MonoDelayElement instantly
    System.out.println(abc.block()); //this will print 'abc', if you are patient enough ;^)
    abc.subscribe(System.out::println); //this will also print 'abc' after 99999999 seconds, but without blocking current thread