【问题标题】:Unable to identify which record is causing oracle exception Spring DATA JPA无法识别导致oracle异常Spring DATA JPA的记录
【发布时间】:2019-04-16 17:10:00
【问题描述】:

我有一个用 @Transactional 注释的方法,我们正在使用 spring-data-jpa 库的 SimpleJPARepository 类的 save(Iterable entity) 方法进行批量更新。我有一个场景,我有近 20000 条记录正在通过这种方法处理。正如 oracle 列所期望的那样,似乎很少有实体在数据类型方面没有很好地形成。例如:实体的属性名的值为“1234”(oracle DB 不接受,因为 DB 中的数据类型为 VARCHAR)。

由于 20000 条记录中很少有记录存在此问题,因此 save(Iterable entity) 方法会抛出“java.sql.SQLSyntaxErrorException: ORA-01722: invalid number”异常并且不会保存任何 20000 条记录。有没有办法我可以识别哪些记录导致此异常并排除它们以在数据库中更新?

我看到有几个选项,例如 DOMAIN 类中的验证(这对我来说不是很可行,因为我有很多域类并且更改它们将对我的应用程序产生很大影响)。我看到的另一种选择是使用“JPA 批量插入与 Hibernate”。同样,即使使用这种批量插入方法,我也不确定是否可以获得有关导致异常的记录的信息。

关于这个问题的任何建议都会有很大帮助。

【问题讨论】:

  • 您是否尝试过在 try 块中使用 save(S entity); 并在 catch 块中记录导致异常的对象?
  • 感谢您的回复。我没有尝试使用该方法 save(S entity);由于记录的数量,我的申请流程非常高。通常我的应用程序处理 20k 到 30k 条记录。我觉得单独击中 DB 的次数在性能方面并不好。如果我错了,请纠正我
  • saveAll 在内部对可迭代对象进行循环,因此性能相同甚至更差,因为它返回已保存元素的List,而执行save (S entity) 您不需要将保存的实体存储在List 中。看源码:github.com/spring-projects/spring-data-jpa/blob/master/src/main/…如果你关心性能你应该看看批处理操作。

标签: oracle spring-data-jpa


【解决方案1】:

您似乎想做的是让数据库验证您的数据。

总的来说,我认为这是一个坏主意,但它不适用于 JPA。

即使您声明不想修复损坏的域模型,这正是您应该做的:

  • 更改实体,以便使用的类型与数据库中使用的类型匹配。请注意,尝试在VARCHARVARCHAR2 列中存储"1234"1234 的值不会触发异常ORA-01722: invalid number,因为没有尝试将任何内容转换为数字,即使它会,这两个值都是数字或可以轻松解析为数字。

  • 添加验证以确保那些不能用类型表示的约束(例如字符串的长度)。

替代方案将是如下过程:

  1. 保存一批实体。

  2. 如果提交成功。完成。

  3. 如果不成功,则将批次拆分为更小的批次并从 1 开始重复。

这既丑陋又慢,可能有助于找到您需要检查的所有约束,但它不是过滤掉那些与您的数据库不匹配的记录的好方法。

【讨论】:

    猜你喜欢
    • 2018-01-14
    • 1970-01-01
    • 2019-02-03
    • 2013-03-31
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    • 2022-01-12
    • 2018-02-15
    相关资源
    最近更新 更多