java 使用身份标识符生成器时,Hibernate 禁用插入批处理
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27697810/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hibernate disabled insert batching when using an identity identifier generator
提问by Youssef
The Hibernate documentation says:
休眠文档说:
Hibernate disables insert batching at the JDBC level transparently if you use an identity identifier generator.
如果您使用身份标识符生成器,Hibernate 会在 JDBC 级别透明地禁用插入批处理。
But all my entities have this configuration:
但我所有的实体都有这样的配置:
@Id
@GeneratedValue(strategy = javax.persistence.GenerationType.IDENTITY)
private Integer id;
When I'm using this identity above So
当我在上面使用这个身份时
- what's the problem with
IDENTITY
? - is the batch insert disabled?
- How can I solve this?
- 有什么问题
IDENTITY
? - 批量插入被禁用了吗?
- 我该如何解决这个问题?
回答by Vlad Mihalcea
Hibernate tries to defer the Persistence Context flushing up until the last possible moment. This strategy has been traditionally known as transactional write-behind.
The write-behind is more related to Hibernate flushing rather than any logical or physical transaction. During a transaction, the flush may occur multiple times.
The flushed changes are visible only for the current database transaction. Until the current transaction is committed, no change is visible by other concurrent transactions.
The IDENTITY generatorallows an integer/bigint column to be auto-incremented on demand. The increment process happens outside of the current running transaction, so a roll-back may end up discarding already assigned values (value gaps may happen).
The increment process is very efficient since it uses a database internal lightweight locking mechanism as opposed to the more heavyweight transactional course-grain locks.
The only drawback is that we can't know the newly assigned value prior to executing the INSERT statement. This restriction is hindering the “transactional write behind” flushing strategy adopted by Hibernate. For this reason, Hibernates disables the JDBC batch support for entities using the IDENTITY generator.
The only solution would be to use a TABLE identifier generator, backed by a pooled-lo optimizer. This generator works with MySQL too, so it overcomes the lack of database SEQUENCE support. However, the TABLE generator performs worse than IDENTITY, so in the end, this is not a viable alternative. Therefore, using IDENTITY is still the best choice on MySQL, and if you need batching for insert, you can use jOOQ for that. Hibernate and jOOQ are a great combo.
Hibernate 尝试将 Persistence Context 刷新推迟到最后可能的时刻。这种策略传统上被称为事务性后写。
write-behind 与 Hibernate 刷新更相关,而不是任何逻辑或物理事务。在一个事务中,flush 可能会发生多次。
刷新的更改仅对当前数据库事务可见。在提交当前事务之前,其他并发事务看不到任何更改。
所述IDENTITY发生器允许的整数/ BIGINT列是自动递增上的需求。增量过程发生在当前正在运行的事务之外,因此回滚可能最终会丢弃已分配的值(可能会发生值差距)。
增量过程非常有效,因为它使用数据库内部轻量级锁定机制,而不是更重量级的事务性粗粒锁。
唯一的缺点是我们无法在执行 INSERT 语句之前知道新分配的值。这种限制阻碍了 Hibernate 采用的“事务性写入”刷新策略。出于这个原因,Hibernates 禁用了对使用 IDENTITY 生成器的实体的 JDBC 批处理支持。
唯一的解决方案是使用 TABLE 标识符生成器,由pooled-lo 优化器支持。这个生成器也适用于 MySQL,因此它克服了缺乏数据库 SEQUENCE 支持的问题。然而,TABLE 生成器的性能比 IDENTITY 差,所以最终,这不是一个可行的替代方案。因此,在 MySQL 上使用 IDENTITY 仍然是最好的选择,如果您需要批量插入,您可以使用 jOOQ。Hibernate 和 jOOQ 是一个很好的组合。