首页 > 解决方案 > 无法识别哪个记录导致oracle异常Spring DATA JPA

问题描述

我有一个用 @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”。同样,即使使用这种批量插入方法,我也不确定是否可以获得有关导致异常的记录的信息。

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

标签: oraclespring-data-jpa

解决方案


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

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

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

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

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

替代方案将是如下过程:

  1. 坚持一批实体。

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

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

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


推荐阅读