使用 withBatch 处理 BatchUpdateException

Handling BatchUpdateException using withBatch

我正在遍历一组对象,将它们插入到我的 PostgreSQL 数据库中,如下所示:

sql.withTransaction {
    try {
        sql.withBatch(1000, 'insert into category (id, version, name, parent_id) values (:id, :version, :name, :parent_id);') { stmt ->
            categoryInserts.each {
                try {
                    stmt.addBatch([id: it.id, version: 0, name: it.name, parent_id: it.parent?.id])
                } catch (SQLException e) {
                    log.error("Category ${it.name} with parent ${it.parent?.id} could not be inserted.")
                }
            }
         }
      } catch (BatchUpdateException e) {
          log.error("Categories could not be inserted.")
      }
      sql.commit()
}

类别table 有一个唯一约束(名称,parent_id)。如果违反约束,程序将捕获 BatchUpdateException 并且不会插入后续对象。不幸的是,在执行 addBatch 方法时没有抛出异常。

有什么方法可以继续 withBatch 语句,以便忽略重复项并插入新记录?批量插入不提供这种行为对我来说似乎很奇怪。

我用 Alexandros 评论中提到的 post 解决了这个问题。解决方案现在如下所示:

sql.withTransaction {
    try {
        sql.withBatch(1000, 'insert into category (id, version, name, parent_id) ' +
        'select :id, :version, :name, :parent_id ' +
        'where not exists (select name, parent_id from category where name = :name and parent_id = :parent_id);') { stmt ->
            categoryInserts.each {
                try {
                    stmt.addBatch([id: it.id, version: 0, name: it.name, parent_id: it.parent?.id])
                } catch (SQLException e) {
                  log.error("Category ${it.name} with parent ${it.parent?.id} could not be inserted.")
                }
            }
        }
    } catch (BatchUpdateException e) {
        log.error("Categories could not be inserted.", e)
    }

    sql.commit()
}

请注意,这可以通过 SQL 的 postgresql 方言解决。对于其他 DBMS,在 withBatch 方法中使用 SQL 过程可能是一种有用的方法。

如果有人知道用标准-SQL做到这一点的方法,请给我提示。