【问题标题】:Using batch insert in Hibernate/JPA在 Hibernate/JPA 中使用批量插入
【发布时间】:2016-11-20 07:26:53
【问题描述】:

好吧,我正在尝试在 JPA 中进行批量插入,但我认为这不起作用。

我的方法是这样的:

public void saveBatch(List<? extends AbstractBean> beans) {
    try {
        begin();
        logger.info("Salvando em batch " + beans.size() + " bean(s)");
        for (int i = 0; i < beans.size(); i++) {
        if (i % 50 == 0) {
            entityManager.flush();
            entityManager.clear();
        }
        entityManager.merge(beans.get(i));

        }
        commit();
    } catch (Exception e) {
        logger.error("Ocorreu um erro ao tentar salvar batch. MSG ORIGINAL: "
                + e.getMessage());
        rollback();
        throw new DAOException("Ocorreu um erro ao tentar salvar batch");
    }
    }

我的想法是休眠将每 50 行:

insert into tableA values (),(),()...

但是查看日志我看到每个 merge() 命令都有一个 INSERT 链接:

insert into tableA values ()
insert into tableA values ()
insert into tableA values ()
insert into tableA values ()

怎么了?这是正确的?

【问题讨论】:

  • 你的 JPA impl 是什么。它取决于。您是否修改了 JPA conf 以启用它?如果是,如何?
  • 我的 jpa 是 2.1,使用休眠。我没有在 jpa 配置中修改任何内容。
  • 你的假设是错误的。 Hibernate 不会生成单个庞大的 SQL 语句,而是会采用一批(插入)语句(在您的情况下为 50 个)并在一次往返中同时将它们传递到数据库中(当EntityManager#flush()(或最后提交) ) 被执行)
  • 我读过这篇文章,但我已经在使用 entityManager 和最低值批量大小 = 50

标签: java hibernate jpa


【解决方案1】:

Hibernate 默认不启用批处理。您将需要考虑以下settings(我认为至少需要batch_size 才能使任何批量插入/更新工作):

hibernate.jdbc.batch_size

非零值允许 Hibernate 使用 JDBC2 批量更新。例如 推荐值在 5 到 30 之间

hibernate.jdbc.batch_versioned_data

如果您的 JDBC 驱动程序返回正确的行,则将此属性设置为 true 从 executeBatch() 开始计数。打开此选项通常是安全的。 然后 Hibernate 将使用批处理 DML 来处理自动版本化的数据。 默认为假。例如真实 |假的

hibernate.order_updates (similarly, hibernate.order_inserts)

强制 Hibernate 按主键值对 SQL 更新进行排序 正在更新的项目。这将导致更少的事务死锁 在高度并发的系统中。例如真实 |假的

【讨论】:

  • 我在persistente.xml 中添加了batch_size,但问题仍然存在。如果我控制它,我不明白为什么我应该使用这个属性。
猜你喜欢
  • 2011-02-15
  • 1970-01-01
  • 2021-04-23
  • 1970-01-01
  • 2013-07-23
  • 2010-09-09
  • 1970-01-01
  • 2016-02-27
  • 2014-10-14
相关资源
最近更新 更多