Hibernate 文档说:
Hibernate disables insert batching at the JDBC level transparently if you use an identity identifier generator.
但是我所有的实体都有这个配置:
@Id
@GeneratedValue(strategy = javax.persistence.GenerationType.IDENTITY)
private Integer id;
当我在 So 上面使用这个身份时
IDENTITY
有什么问题?- 是否禁用了批量插入?
- 我该如何解决这个问题?
最佳答案
事务性后写
Hibernate 尝试将持久性上下文刷新延迟到最后可能的时刻。这种策略传统上被称为事务性后写。
write-behind 与 Hibernate 刷新有关,而不是任何逻辑或物理事务。在事务期间,刷新可能会发生多次。
刷新的更改仅对当前数据库事务可见。在提交当前事务之前,其他并发事务看不到任何更改。
身份
IDENTITY
生成器允许 int
或 bigint
列按需自动递增。递增过程发生在当前正在运行的事务之外,因此回滚可能最终会丢弃已分配的值(可能发生值间隙)。
增量过程非常有效,因为它使用数据库内部的轻量级锁定机制,而不是更重量级的事务性进程锁。
唯一的缺点是在执行 INSERT 语句之前我们无法知道新分配的值。这种限制阻碍了 Hibernate 采用的事务性后写刷新策略。出于这个原因,Hibernates 使用 IDENTITY
生成器禁用了对实体的 JDBC 批处理支持。
表格
唯一的解决方案是使用由 pooled-lo
支持的 TABLE
标识符生成器。优化器。此生成器也适用于 MySQL,因此它克服了缺乏数据库 SEQUENCE 支持的问题。
但是,TABLE
生成器的性能比 IDENTITY
差,所以最后,这不是一个可行的替代方案。
结论
因此,在 MySQL 上使用 IDENTITY 仍然是最好的选择,如果需要批量插入,可以使用 JDBC。
关于java - 为什么 Hibernate 在使用 IDENTITY 标识符生成器时禁用 INSERT 批处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27697810/