主键上带有Hibernate Oracle序列重复值的JBoss EAP 6.x

主键上带有Hibernate Oracle序列重复值的JBoss EAP 6.x,oracle,hibernate,jpa,wildfly,sequence,Oracle,Hibernate,Jpa,Wildfly,Sequence,我已经使用纯JPA注释定义了许多Hibernate实体。它们在我的数据库上使用预定义的Oracle序列来自动生成主键值 @Id @SequenceGenerator(name = "USERS_ID_GENERATOR", sequenceName = "MY_SEQ") @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USERS_ID_GENERATOR") @Column(name = "U_ID", upda

我已经使用纯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;
当它被部署到JBoss EAP 6.1时,所有的功能最初都很好,但是在一段短时间之后,Hibernate开始在插入时生成重复的键(ORA-00001错误)


我不关心id顺序或间隙,但不能容忍重复的密钥。。。这里发生了什么?

这没有很好的文档记录,这里和其他站点上的许多解决方案都与hibernate的旧版本有关,HiLo sequenceGenerator是默认版本。但经过调查,我发现根本原因是JBoss EAP 6集

hibernate.id.new_generator_mappings=true 
默认情况下,它使用org.org.hibernate.id.enhanced.SequenceStyleGenerator而不是旧版本

Hibernate SequenceStyleGenerator的默认增量为1(检查代码!),但是JPA将此生成器中的增量值覆盖为50。这意味着生成器查看序列nextval,并从nextval-49开始保留50个ID的缓存以供使用。当这些数据耗尽时,生成器从oracle读取下一个序列,并重复该过程。因此,一旦第一系列ID用完,我们就开始看到重复的密钥

因此,决议是:

1) 定义增量值为50的Oracle序列以匹配JPA默认值

CREATE SEQUENCE MY_SEQ
START WITH 50
MAXVALUE 9999999999999999999
INCREMENT BY 50
NOCYCLE;

2) 将allocationSize=1添加到@SequenceGenerator注释中-这将强制SequenceGenerator返回以从oracle序列中读取所需每个ID的下一个值(可能会影响性能)

,或

3) 通过其他值定义Oracle序列增量,并确保allocationSize匹配


回答了我自己的问题,希望能帮助解决这个问题的其他人。

你的回答是正确的;只是更多的细节

有些帖子建议关闭 hibernate.id.new_生成器_映射=false

但是根据

两者之间是有区别的 GenerationType.AUTO和GenerationType.SEQUENCE

如果选择“自动”,则将选择hibernate本机。 如果您选择SEQUENCE,您将匹配hilo算法进行序列分配,这与SequenceStyleGenerator完全不同。 如果切换hibernate.id.new\u generator\u mappings=true/false,则这将不兼容

因此答案1)绝对是正确的/遵循当前Hibernate/Jboss的建议

…答案设置allocationSize=1到所有实体不是一个好的解决方案。 看见

虽然我正在搜索其他信息,但您添加信息作为帮助他人的答案的方式值得+1。谢谢@skay,我已经为答案2)添加了关于单个Allocaints的潜在性能影响的说明。如果序列是用“order”设置的,这在RAC环境中可能特别明显。注意——链接中的JBoss文档提到这是Hibernate 4.x设置。Hibernate3也支持它。在我们的应用程序中将其与3.6.0.Final一起使用。。JBossAS7附带了4.x,因此他们的文档是如何引用它的。
 @SequenceGenerator(name = "USERS_ID_GENERATOR", sequenceName = "MY_SEQ", allocationSize = 1)