java - Hibernate 不批量插入

标签 java postgresql hibernate spring-data timescaledb

我希望你能帮助我解决这个问题,因为我现在真的一无所知,而且到目前为止没有任何相关问题可以帮助我。

我有一个实体集合,我想通过 spring-data saveAll() 批量插入到 TimescaleDB(Postgresql 的扩展)中,我以为我按照书本配置了所有内容,但 hibernate 统计信息从不反射(reflect)批量插入:

1223268 nanoseconds spent acquiring 1 JDBC connections;

0 nanoseconds spent releasing 0 JDBC connections;

34076442411 nanoseconds spent executing 3408 JDBC statements;

0 nanoseconds spent executing 0 JDBC batches;

我的 Hibernate 属性是通过 HibernatePropertiesCustomizer 配置的,如下所示:

props.put("hibernate.generate_statistics", true);
props.put("hibernate.order_inserts", true);
props.put("hibernate.order_updates", true);
props.put("hibernate.jdbc.batch_size", "100");

我通过调用验证了在 saveAll() 期间确实存在事务上下文:

TransactionSynchronizationManager.isSynchronizationActive()

实体的 ID 如下所示。没有 @GenerateValue 或 @SequenceGenerator 注释,因为我使用数据的时间戳(来自 Web API)作为 ID。

@Id
@Column
private Instant time;

我什至尝试通过调整我的连接字符串来控制重写行为,但它没有帮助:

jdbc:postgresql://localhost:5432/db?reWriteBatchedInserts=true&currentSchema=finance-data

我使用 maven org.postgresql 42.2.9 和 42.2.13 驱动程序对此进行了测试。 Spring Boot 发行版是 2.2.2.RELEASE,它捆绑了 hibernate-core 5.4.9.FINAL 和 spring-jdbc 5.2.2.RELEASE。 timescale docker版本为1.7.1-pg12。

如果您需要更多其他信息,请告诉我。提前致谢!!!

最佳答案

来自this ,它提到如果批量插入的实体是手动分配其 ID ,则必须添加一个 @Version 属性。但对于 PostgreSQL 来说,如果使用 SEQUENCE 生成器生成 ID,则不需要添加 @Version

如果手动分配ID,我不会尝试添加@Version是否可以解决问题,但你可以尝试一下。我个人使用 SEQUENCE 生成器来生成 ID,它无需在 PostgreSQL 中添加 @Version 即可工作。

为了在使用SEQUENCE生成器时有效地生成ID,我还更改为使用this中提到的“pooled”或“pooled-lo”算法以减少获取 ID 的数据库往返次数。

这是我所做的:

@Entity
public class Foo {


    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="foo_sequence")
    @SequenceGenerator(name="foo_sequence", sequenceName = "foo_id_seq", allocationSize = 100)
    private Long id;

}

以及 hibernate 设置:

hibernate.order_inserts = true
hibernate.order_updates = true
hibernate.jdbc.batch_size = 50
hibernate.jdbc.batch_versioned_data = true

# For using "pool-lo" optimiser for generating ID when using JPA @SequenceGenerator
hibernate.id.optimizer.pooled.preferred = pooled-lo

还需要确保 PostreSQL 中的序列与 @SequenceGenerator 中配置的序列一致:

alter sequence foo_id_seq increment by 100;

为了完整起见,对于 PostgreSQL,还要在 JDBC 连接字符串中添加 reWriteBatchedInserts=true ,这可以提供 2-3 倍的性能提升,如 docs 所说。 .

关于java - Hibernate 不批量插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62244991/

相关文章:

java - SOAP:将方法从 AXIS 1.4 迁移到 CXF 以添加新 header

database - Postgres order by foreign key 性能?

postgresql - 如何使用 libpq 的 pgpass 连接到 postgresql,而不指定纯文本密码?

java - 从数据库中保存/检索二进制数据

java - 为什么我只能在实体类上放置 NamedQuery 注释

java - 如何使 Ant 任务对我的所有 JAR 文件进行签名和打包?

java - 通过 exec 或 shell_exec 执行 java 会出错

postgresql - 如何配置 postgresql 不记录插入数据库的实际数据?

java - 使用 Flyway 和 Hibernate 的 hbm2ddl 在应用程序的生命周期中管理数据库模式

java - 如何在 Java 中比较字符串?