sho*_*ser 7 oracle hibernate jpa sequence wildfly
我已经使用纯JPA注释定义了许多Hibernate实体.它们在我的数据库上使用预定义的Oracle序列来自动生成主键值.
@Id
@SequenceGenerator(name = "USERS_ID_GENERATOR", sequenceName = "MY_SEQ")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USERS_ID_GENERATOR")
@Column(name = "U_ID", updatable = false, unique = true, nullable = false, precision = 19)
private Long id;
Run Code Online (Sandbox Code Playgroud)
当它部署到JBoss EAP 6.1时,一切都运行良好,但是在短时间内Hibernate开始在插入上生成重复键(ORA-00001错误).
我不关心id的排序或差距,但不能容忍重复的密钥......这里发生了什么?
sho*_*ser 13
这没有很好的文档记录,这里和其他站点的许多解决方案都与hibernate的旧版本相关,其中HiLo sequenceGenerator是默认的.但经过调查,我发现其根本原因是JBoss EAP 6套装
hibernate.id.new_generator_mappings=true
Run Code Online (Sandbox Code Playgroud)
默认情况下,它使用org.org.hibernate.id.enhanced.SequenceStyleGenerator而不是旧版本.
Hibernate SequenceStyleGenerator默认增量为1(检查代码!),但是JPA会将此生成器中的增量值覆盖为50.这意味着Generator会查看序列nextval,并保持50个ID的缓存,从nextval开始 - 49.当这些用完时,生成器从oracle读取下一个序列,并重复该过程.因此,一旦第一系列的ID耗尽,我们就会开始看到重复的键.
所以决议是:
1)使用增量值50定义Oracle序列以匹配JPA默认值
CREATE SEQUENCE MY_SEQ
START WITH 50
MAXVALUE 9999999999999999999
INCREMENT BY 50
NOCYCLE;
Run Code Online (Sandbox Code Playgroud)
要么
2)在@SequenceGenerator注释中添加allocationSize = 1 - 这会强制SequenceGenerator返回从oracle序列中读取其所需的每个ID的下一个值(具有潜在的性能影响)
@SequenceGenerator(name = "USERS_ID_GENERATOR", sequenceName = "MY_SEQ", allocationSize = 1)
Run Code Online (Sandbox Code Playgroud)
, 要么
3)定义Oracle序列INCREMENT BY其他一些值,并确保allocationSize匹配.
回答了我自己的问题,希望能帮助其他人解决这个问题.
| 归档时间: |
|
| 查看次数: |
2559 次 |
| 最近记录: |