首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有没有办法通过Spring Boot和Hibernate使用postgres批量插入带有UUID主键的实体?

有没有办法通过Spring Boot和Hibernate使用postgres批量插入带有UUID主键的实体?
EN

Stack Overflow用户
提问于 2021-06-02 11:50:10
回答 2查看 384关注 0票数 2

据我所知,我已经完成了我的家庭作业。我知道自动生成的密钥不能插入。但是对于作为UUID的主键,我该如何解决这个问题呢?

我有这个主键配置

代码语言:javascript
复制
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
private UUID id;

我希望这不被认为是一种“自动”策略,但它似乎是,因为我的实体仍然是单独插入的,用10k插入破坏了我的性能。为什么这不能被认为是序列策略?UUID无论如何都保证是唯一的,所以不应该有任何技术上的东西,仅仅是生成一些UUID并批量插入它们。

我的application.properties中确实有适当的设置:

代码语言:javascript
复制
spring.jpa.properties.hibernate.jdbc.batch_size=50
spring.jpa.properties.hibernate.order_inserts=true
spring.jpa.properties.hibernate.order_updates=true
spring.jpa.properties.hibernate.jdbc.batch_versioned_data=true

而且我确实使用了PagingAndSortingRepository的方法saveAll来保存实体。

一些日志:

代码语言:javascript
复制
03:12:01.122 |  INFO | o.h.e.i.StatisticalLoggingSessionEventListener | Session Metrics {
    35000 nanoseconds spent acquiring 1 JDBC connections;
    0 nanoseconds spent releasing 0 JDBC connections;
    1533100 nanoseconds spent preparing 8 JDBC statements;
    49660800 nanoseconds spent executing 5 JDBC statements;
    5137013700 nanoseconds spent executing 401 JDBC batches;
    0 nanoseconds spent performing 0 L2C puts;
    0 nanoseconds spent performing 0 L2C hits;
    0 nanoseconds spent performing 0 L2C misses;
    6933591600 nanoseconds spent executing 2 flushes (flushing a total of 60152 entities and 40294 collections);
    244354300 nanoseconds spent executing 5 partial-flushes (flushing a total of 60009 entities and 60009 collections)
}

这很有趣,因为它确实提到了批处理。但是,在启用spring.jpa.show-sql=true的情况下,我看到了数千个日志行,如下所示:

Hibernate: insert into ingestion_id_mapping (derive_ingestion_id, ingestion_id, project_id, metric_id, subject_id) values (?, ?, ?, ?, ?)

这似乎与批处理统计数据中的数字无关。

EN

回答 2

Stack Overflow用户

发布于 2021-06-02 23:35:06

复制您的样例as follows,假设设置了reWriteBatchedInserts jdbc连接属性,它实际上看起来像预期的那样工作:

代码语言:javascript
复制
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres?reWriteBatchedInserts=true

例如,使用spring.jpa.properties.hibernate.jdbc.batch_size=8,当通过repository.saveAll插入8个新创建的实体时,相应的postgres日志将如下所示

代码语言:javascript
复制
postgres_db_1  | 2021-06-02 15:22:54.327 UTC [386] LOG:  
  execute <unnamed>: /* insert org.demo.batchinsert.UuidEntity */
  insert into uuid_entity (id) values ($1),($2),($3),($4),($5),($6),($7),($8)
...
票数 2
EN

Stack Overflow用户

发布于 2021-06-03 15:08:20

实际上,您不能仅仅通过查看hibernate日志来判断批处理是否有效。

您必须使用像P6Spy这样的工具来代理JDBC DriverDatasource。然后,您可能会看到批处理实际上是有效的。

您可以使用这个装饰器:https://github.com/gavlyukovskiy/spring-boot-data-source-decorator

现在,如果您希望加快数据库端的批处理速度,也可以使用属性reWriteBatchedInserts

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67798674

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档