CrudRepository没有提供检查saveall方法是否已提交的方法

问题描述

我正在使用CrudRepository的spring框架的saveAll方法

validationRowRepository.saveAll(validationRows);

现在,当我们确保将当前批处理持久化到数据库中并提交了事务时,我只有执行下一步的要求。

通过查看saveAll方法规范,我决定采用这种方式进行检查。

    List<ValidationRow> savedRows = (List<ValidationRow>) validationRowRepository.saveAll(validationRows);
    if (Objects.equals(savedRows.size(),validationRows.size()) {
        // do the next step.
    }

即使这是真的,那么如果执行不输入if块会发生什么呢? 所以我的问题是: 有没有更合适的方法来实现这种情况。

解决方法

有两点要考虑:

  1. 将数据写入数据库
  2. 提交交易

saveAll的合同如下:

所有实体将被写入数据库。如果这对于至少一个实体不起作用,则将引发异常。 saveAll的返回值将始终具有与输入值相同的大小。它不会包含null值。所有包含的实体都将设置其id值(对象类型不是null,原始数字类型不是0

因此,您的if条件是多余的,并在Spring Data JDBC中测试一个非常特定的错误。有意义的是进行一个测试(作为实际的JUnit测试),以使您的实体可以在保存后加载并看上去像检查一样。基本上,这将是对对象模型,数据库模式,映射和Spring Data JDBC中实现的逻辑的一致性的测试。很多事情可能会出错。对此进行测试很好。

您的代码甚至没有涉及交易的主题。控制交易的主要方法有两种:

  1. @Transactional
  2. TransactionTemplate

两者均基于Spring事务基础结构,该结构可确保在事务提交失败时引发异常。类似于我在上面写的内容,编写一个测试(即检查事务是否按预期运行的JUnit测试)可能有意义。尽管这可能很困难,因为您必须注入某种数据库故障才能做到这一点。

因此,实际代码剩下的就是处理调用saveAll时可能引发的任何异常。由于使用TransactionTemplate更容易移动事务边界,因此我在示例代码中使用了它。

try {
    validationRows = txTemplate.execute( t -> validationRowRepository.saveAll(validationRows));
    process(validationRows) // do whatever you want to do with the entities after saving
} catch (DataAccessException e) {
    // do whatever you see fit in the case of an exception. You might also skip the try catch block and just let the exception terminate the process,or in case of a web application the request.
}
,

如果您致电saveAll,则必须保存数据。在其他情况下,必须抛出异常,然后您才能处理可能的异常。您编写的代码是正确的,并且您确实不需要执行高级安全性。 ;)