我希望你能帮助我解决这个问题,因为我现在真的一无所知,而且到目前为止没有任何相关问题可以帮助我。
我有一个实体集合,我想通过 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¤tSchema=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/