【问题标题】:Why Hybris modelService.save() doesn't work inside the ifPresent() method?为什么 Hybris modelService.save() 在 ifPresent() 方法中不起作用?
【发布时间】:2020-04-29 13:19:16
【问题描述】:
    private void doSomething(someProcessModel process){
        CustomerModel customer = process.getCustomerModel();

        customer.getFoos().stream()
                .filter(foo -> foo.getCountryCode().equals(process.getCountryCode()))
                .findFirst()
                .ifPresent(foo -> {
                    if(foo.getSomeNumber() == null){
                        foo.setSomeNumber("1234567");
                        modelService.save(foo);
                    }
                });
    }

如上面的代码 sn-p 所示,我有一个具有属性“Foos”的“CustomerModel”。这是一对多的关系。正如你所看到的,我已经做了一些过滤,最后,如果它为空,我想更新 'Foo' 的 'someNumber' 属性的值。我已经确认一切正常,因为“someNumber”属性的值在调试期间更新。它根本没有保存,因为我已经在 HMC 中进行了检查。我还验证了拦截器没有任何会引发错误的条件。日志中也没有显示任何内容。

我想知道在“ifPresent()”方法中执行“modelService.save()”是否合法?这里可能存在什么问题?

【问题讨论】:

  • 当然,如果设计不当也是合法的。但是只有当找到这样一个匹配的foo并且它的初始someNumbernull时,它才会保存foo
  • 另一方面,你可能想写customer.getFoos().stream() .filter(foo -> foo.getCountryCode().equals(process.getCountryCode())) .findFirst() .map(foo -> updatedFoo(foo)) // mutate or return new instance from here .ifPresent(foo -> modelService.save(foo));

标签: java-stream optional hybris


【解决方案1】:

我现在找到了根本原因,因为我再次面临同样的问题。

我原来的问题的上下文

为了给我最初的问题提供更多背景信息,#doSomething 方法驻留在 Hybris 业务流程操作类中,并且在运行 #doSomething 方法后,我在调试它(通过停止调试)时提前结束了该操作。

根本原因

上述问题发生在我调试动作类时。我假设 ModelService#save 将在运行后保持业务流程的当前状态。但是,如果出现任何错误,Hybris OOTB 业务流程将执行回滚(我相信这是由于我中途停止调试造成的)。

SAP Commerce Documentation:

所有操作都在它们自己的事务中执行。这意味着在操作 bean run 方法中所做的更改会在出现错误时回滚。

解决方案

让动作完全运行!

很高兴知道

根据 SAP 文档和此 blog post,有时我们需要绕过业务流程回滚,即使引发了异常并且有办法实现这一点。更多信息可以在 SAP Commerce Documentation 和提到的博客文章中找到。

但是,在某些情况下,可能需要让业务异常到达外部,同时提交事务并在外部处理异常。因此,可以使任务引擎不回滚在任务失败期间所做的更改。

【讨论】:

    【解决方案2】:

    您必须谨慎对待模型中的列表,因为它们是不可变的,您必须设置全新的列表。此外,您仅在特定模型上调用 save ,这会更改其 Jalo 引用,这就是您的列表未更新的原因。变异流并最终收集它会创建新列表,这就是您可以直接从模型中流过列表的原因。

    private void doSomething(someProcessModel process){
        CustomerModel customer = process.getCustomerModel();
        ArrayList<FooModel> foos = doSomethingOnFoos(customer.getFoos());
        customer.setFoos(foos);
        modelService.saveAll(foos, customer);
    }
    
    //compare the value you know exists with something that might be NULL as equals can handle that, but not the other way around
    private ArrayList<FooModel> doSomethingOnFoos(ArrayList<FooModel> fooList) {
         return fooList.stream()
                    .filter(Objects::nonNull)
                    .filter(foo -> process.getCountryCode().equals(foo.getCountryCode()))
                    .filter(foo -> Objects.isNull(foo.getSomeNumber()))
                    .map(foo -> foo.setSomeNumber(1234))
                    .collect(toList());
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-03
      • 2019-07-18
      • 2017-03-18
      • 2020-10-02
      • 2011-03-04
      • 2019-04-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多