Java SpringBoot和Hibernate是否有办法使用postgres批量插入UUID主键的实体?

Java SpringBoot和Hibernate是否有办法使用postgres批量插入UUID主键的实体?,java,spring,postgresql,hibernate,jpa,Java,Spring,Postgresql,Hibernate,Jpa,据我所知,我已经完成了家庭作业。我知道无法插入自动生成的密钥。但是对于UUID主键,我该如何解决这个问题呢 我有这个主键配置 @Id @GeneratedValue(generator = "uuid") @GenericGenerator(name = "uuid", strategy = "uuid2") private UUID id; 我希望这不是一种“自动”策略,但似乎是这样,因为我的实体仍在单独插入,用10k插入破坏了我的

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

我有这个主键配置

@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
private UUID id;
我希望这不是一种“自动”策略,但似乎是这样,因为我的实体仍在单独插入,用10k插入破坏了我的性能。为什么不能将其视为顺序策略?UUID无论如何都是唯一的,因此,在生成大量UUID并批量插入它们的过程中不应该有任何技术问题

我的应用程序中确实有相应的设置。属性:

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
我确实使用了
分页和排序存储库
的方法
saveAll
来保存实体

一些日志:

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:插入摄入id映射(派生摄入id、摄入id、项目id、度量id、受试者id)值(?,,,?,?)

它似乎与批处理统计数据中的数字不相关。

复制您的样本时,它实际上似乎按照预期工作,假设设置了
reWriteBatchedInserts
jdbc连接属性:

spring.datasource.url=jdbc:postgresql://localhost:5432/postgres?reWriteBatchedInserts=true
例如使用
spring.jpa.properties.hibernate.jdbc.batch_size=8
,通过
repository插入8个新创建的实体时,相应的postgres日志将如下所示。saveAll

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)
...
postgres|db|1 | 2021-06-02 15:22:54.327 UTC[386]日志:
执行:/*insert org.demo.batchinsert.UuidEntity*/
插入uuid_实体(id)值($1),($2),($3),($4),($5),($6),($7),($8)
...

实际上,仅仅通过查看hibernate日志并不能确定批处理是否有效

您必须使用P6Spy之类的工具代理
JDBC驱动程序
Datasource
。然后您可能会看到批处理实际上正在工作

您可以使用此装饰器进行以下操作:


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

批处理问题与自动策略无关,而与标识策略有关。在这种情况下,AUTO应使用UUIDGenerator。你有一些日志吗?您使用的是哪个版本的PG和hibernate?@CodeScale我使用的是PostgreSQL 13(本地版本)和Spring Boot 2.5.0附带的hibernate,基本上是前沿版本。我对另一个实体做了更多的实验,该实体有一个@EmbeddedId,其形式为2个外部UUID键,但即使在插入之前,它也开始通过这些UUID检索单独的行。就在那时,我决定放弃使用SQLInsert。太多的魔法我无法调试。你有日志吗?类似于由
spring.jpa.properties.hibernate.generate\u statistics=true生成的property@CodeScale我再次运行它,现在启用了日志记录。然而,令人困惑的结果。Insert语句似乎是以2的倍数成批处理的,因此当需要例如7次插入时,执行的插入将一次插入4、2和1个值(在查看数据库日志时,这可能会令人困惑)。无论如何,这是一个有趣的postgres选项,谢谢。不幸的是,通常情况下,简单的例子并不能说明问题。可能是我的项目中的各种实体的组合导致了这种情况。reWriteBatchedInserts是为了提高数据库端的性能,但它仅在客户端批量发送语句时才相关。。。如果没有,这根本没有任何影响…@sebastiaan,欢迎你。从hibernate日志中可以看出,单次插入的语句被分批发送到DB,然后DB执行单次语句。RewriteBatchedInsert选项是否更改了查询?